Loading django/db/models/base.py +11 −4 Original line number Diff line number Diff line Loading @@ -1479,7 +1479,17 @@ class Model(six.with_metaclass(ModelBase)): def _check_ordering(cls): """ Check "ordering" option -- is it a list of strings and do all fields exist? """ if not cls._meta.ordering: if cls._meta._ordering_clash: return [ checks.Error( "'ordering' and 'order_with_respect_to' cannot be used together.", hint=None, obj=cls, id='models.E021', ), ] if cls._meta.order_with_respect_to or not cls._meta.ordering: return [] if not isinstance(cls._meta.ordering, (list, tuple)): Loading @@ -1502,9 +1512,6 @@ class Model(six.with_metaclass(ModelBase)): # Convert "-field" to "field". fields = ((f[1:] if f.startswith('-') else f) for f in fields) fields = (f for f in fields if f != '_order' or not cls._meta.order_with_respect_to) # Skip ordering in the format field1__field2 (FIXME: checking # this format would be nice, but it's a little fiddly). fields = (f for f in fields if '__' not in f) Loading django/db/models/options.py +4 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ class Options(object): self.verbose_name_plural = None self.db_table = '' self.ordering = [] self._ordering_clash = False self.unique_together = [] self.index_together = [] self.select_on_save = False Loading Loading @@ -234,6 +235,9 @@ class Options(object): if self.verbose_name_plural is None: self.verbose_name_plural = string_concat(self.verbose_name, 's') # order_with_respect_and ordering are mutually exclusive. self._ordering_clash = bool(self.ordering and self.order_with_respect_to) # Any leftover attributes must be invalid. if meta_attrs != {}: raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys())) Loading docs/ref/checks.txt +2 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ Models ``<M2M field>``. Maximum length is ``<maximum length>`` for database ``<alias>``. * **models.E020**: The ``<model>.check()`` class method is currently overridden. * **models.E021**: ``ordering`` and ``order_with_respect_to`` cannot be used together. Fields ~~~~~~ Loading docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,9 @@ Models <django.db.models.Model.delete>` to allow deleting only a child's data in a model that uses multi-table inheritance. * Added a system check to prevent defining both ``Meta.ordering`` and ``order_with_respect_to`` on the same model. CSRF ^^^^ Loading tests/invalid_models_tests/test_models.py +44 −0 Original line number Diff line number Diff line Loading @@ -566,6 +566,50 @@ class OtherModelTests(IsolatedModelsTestCase): ] self.assertEqual(errors, expected) def test_just_ordering_no_errors(self): class Model(models.Model): order = models.PositiveIntegerField() class Meta: ordering = ['order'] self.assertEquals(Model.check(), []) def test_just_order_with_respect_to_no_errors(self): class Question(models.Model): pass class Answer(models.Model): question = models.ForeignKey(Question) class Meta: order_with_respect_to = 'question' self.assertEquals(Answer.check(), []) def test_ordering_with_order_with_respect_to(self): class Question(models.Model): pass class Answer(models.Model): question = models.ForeignKey(Question) order = models.IntegerField() class Meta: order_with_respect_to = 'question' ordering = ['order'] errors = Answer.check() expected = [ Error( "'ordering' and 'order_with_respect_to' cannot be used together.", hint=None, obj=Answer, id='models.E021', ), ] self.assertEqual(errors, expected) def test_non_valid(self): class RelationModel(models.Model): pass Loading Loading
django/db/models/base.py +11 −4 Original line number Diff line number Diff line Loading @@ -1479,7 +1479,17 @@ class Model(six.with_metaclass(ModelBase)): def _check_ordering(cls): """ Check "ordering" option -- is it a list of strings and do all fields exist? """ if not cls._meta.ordering: if cls._meta._ordering_clash: return [ checks.Error( "'ordering' and 'order_with_respect_to' cannot be used together.", hint=None, obj=cls, id='models.E021', ), ] if cls._meta.order_with_respect_to or not cls._meta.ordering: return [] if not isinstance(cls._meta.ordering, (list, tuple)): Loading @@ -1502,9 +1512,6 @@ class Model(six.with_metaclass(ModelBase)): # Convert "-field" to "field". fields = ((f[1:] if f.startswith('-') else f) for f in fields) fields = (f for f in fields if f != '_order' or not cls._meta.order_with_respect_to) # Skip ordering in the format field1__field2 (FIXME: checking # this format would be nice, but it's a little fiddly). fields = (f for f in fields if '__' not in f) Loading
django/db/models/options.py +4 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ class Options(object): self.verbose_name_plural = None self.db_table = '' self.ordering = [] self._ordering_clash = False self.unique_together = [] self.index_together = [] self.select_on_save = False Loading Loading @@ -234,6 +235,9 @@ class Options(object): if self.verbose_name_plural is None: self.verbose_name_plural = string_concat(self.verbose_name, 's') # order_with_respect_and ordering are mutually exclusive. self._ordering_clash = bool(self.ordering and self.order_with_respect_to) # Any leftover attributes must be invalid. if meta_attrs != {}: raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys())) Loading
docs/ref/checks.txt +2 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ Models ``<M2M field>``. Maximum length is ``<maximum length>`` for database ``<alias>``. * **models.E020**: The ``<model>.check()`` class method is currently overridden. * **models.E021**: ``ordering`` and ``order_with_respect_to`` cannot be used together. Fields ~~~~~~ Loading
docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -164,6 +164,9 @@ Models <django.db.models.Model.delete>` to allow deleting only a child's data in a model that uses multi-table inheritance. * Added a system check to prevent defining both ``Meta.ordering`` and ``order_with_respect_to`` on the same model. CSRF ^^^^ Loading
tests/invalid_models_tests/test_models.py +44 −0 Original line number Diff line number Diff line Loading @@ -566,6 +566,50 @@ class OtherModelTests(IsolatedModelsTestCase): ] self.assertEqual(errors, expected) def test_just_ordering_no_errors(self): class Model(models.Model): order = models.PositiveIntegerField() class Meta: ordering = ['order'] self.assertEquals(Model.check(), []) def test_just_order_with_respect_to_no_errors(self): class Question(models.Model): pass class Answer(models.Model): question = models.ForeignKey(Question) class Meta: order_with_respect_to = 'question' self.assertEquals(Answer.check(), []) def test_ordering_with_order_with_respect_to(self): class Question(models.Model): pass class Answer(models.Model): question = models.ForeignKey(Question) order = models.IntegerField() class Meta: order_with_respect_to = 'question' ordering = ['order'] errors = Answer.check() expected = [ Error( "'ordering' and 'order_with_respect_to' cannot be used together.", hint=None, obj=Answer, id='models.E021', ), ] self.assertEqual(errors, expected) def test_non_valid(self): class RelationModel(models.Model): pass Loading