Fixed #24479 -- Added system check to prevent both ordering and order_wrt.

This commit is contained in:
Jon Dufresne 2015-03-17 07:42:53 -07:00 committed by Tim Graham
parent e304e13448
commit 966a29c2b8
5 changed files with 64 additions and 4 deletions

View File

@ -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)):
@ -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)

View File

@ -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
@ -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()))

View File

@ -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
~~~~~~

View File

@ -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
^^^^

View File

@ -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