diff options
author | Fabio Sangiovanni <sjh+github@sanjioh.org> | 2020-01-20 20:50:30 +0100 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-02-19 09:36:23 +0100 |
commit | b457068cf272bc9912187a2b7aaaa4445110735e (patch) | |
tree | d06738e90a1032b1d389af8176a96a97d64190b0 /tests/admin_changelist | |
parent | d270c10a723ca04e467e08d6d8b38ae392191f2d (diff) | |
download | django-b457068cf272bc9912187a2b7aaaa4445110735e.tar.gz |
Fixed #31187 -- Fixed detecting of existing total ordering in admin changelist when using Meta.constraints.
Detection of existing total ordering in admin changelist now takes into
account non-partial unique constraints.
Diffstat (limited to 'tests/admin_changelist')
-rw-r--r-- | tests/admin_changelist/tests.py | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index a4c220cb15..fa29886160 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -1058,6 +1058,98 @@ class ChangeListTests(TestCase): with self.subTest(ordering=ordering): self.assertEqual(change_list._get_deterministic_ordering(ordering), expected) + @isolate_apps('admin_changelist') + def test_total_ordering_optimization_meta_constraints(self): + class Related(models.Model): + unique_field = models.BooleanField(unique=True) + + class Meta: + ordering = ('unique_field',) + + class Model(models.Model): + field_1 = models.BooleanField() + field_2 = models.BooleanField() + field_3 = models.BooleanField() + field_4 = models.BooleanField() + field_5 = models.BooleanField() + field_6 = models.BooleanField() + nullable_1 = models.BooleanField(null=True) + nullable_2 = models.BooleanField(null=True) + related_1 = models.ForeignKey(Related, models.CASCADE) + related_2 = models.ForeignKey(Related, models.CASCADE) + related_3 = models.ForeignKey(Related, models.CASCADE) + related_4 = models.ForeignKey(Related, models.CASCADE) + + class Meta: + constraints = [ + *[ + models.UniqueConstraint(fields=fields, name=''.join(fields)) + for fields in ( + ['field_1'], + ['nullable_1'], + ['related_1'], + ['related_2_id'], + ['field_2', 'field_3'], + ['field_2', 'nullable_2'], + ['field_2', 'related_3'], + ['field_3', 'related_4_id'], + ) + ], + models.CheckConstraint(check=models.Q(id__gt=0), name='foo'), + models.UniqueConstraint( + fields=['field_5'], + condition=models.Q(id__gt=10), + name='total_ordering_1', + ), + models.UniqueConstraint( + fields=['field_6'], + condition=models.Q(), + name='total_ordering', + ), + ] + + class ModelAdmin(admin.ModelAdmin): + def get_queryset(self, request): + return Model.objects.none() + + request = self._mocked_authenticated_request('/', self.superuser) + site = admin.AdminSite(name='admin') + model_admin = ModelAdmin(Model, site) + change_list = model_admin.get_changelist_instance(request) + tests = ( + # Unique non-nullable field. + (['field_1'], ['field_1']), + # Unique nullable field. + (['nullable_1'], ['nullable_1', '-pk']), + # Related attname unique. + (['related_1_id'], ['related_1_id']), + (['related_2_id'], ['related_2_id']), + # Related ordering introspection is not implemented. + (['related_1'], ['related_1', '-pk']), + # Composite unique. + (['-field_2', 'field_3'], ['-field_2', 'field_3']), + # Composite unique nullable. + (['field_2', '-nullable_2'], ['field_2', '-nullable_2', '-pk']), + # Composite unique and nullable. + ( + ['field_2', '-nullable_2', 'field_3'], + ['field_2', '-nullable_2', 'field_3'], + ), + # Composite field and related field name. + (['field_2', '-related_3'], ['field_2', '-related_3', '-pk']), + (['field_3', 'related_4'], ['field_3', 'related_4', '-pk']), + # Composite field and related field attname. + (['field_2', 'related_3_id'], ['field_2', 'related_3_id']), + (['field_3', '-related_4_id'], ['field_3', '-related_4_id']), + # Partial unique constraint is ignored. + (['field_5'], ['field_5', '-pk']), + # Unique constraint with an empty condition. + (['field_6'], ['field_6']), + ) + for ordering, expected in tests: + with self.subTest(ordering=ordering): + self.assertEqual(change_list._get_deterministic_ordering(ordering), expected) + def test_dynamic_list_filter(self): """ Regression tests for ticket #17646: dynamic list_filter support. |