Fixed #24479 -- Added system check to prevent both ordering and order_wrt.
This commit is contained in:
parent
e304e13448
commit
966a29c2b8
|
@ -1479,7 +1479,17 @@ class Model(six.with_metaclass(ModelBase)):
|
||||||
def _check_ordering(cls):
|
def _check_ordering(cls):
|
||||||
""" Check "ordering" option -- is it a list of strings and do all fields
|
""" Check "ordering" option -- is it a list of strings and do all fields
|
||||||
exist? """
|
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 []
|
return []
|
||||||
|
|
||||||
if not isinstance(cls._meta.ordering, (list, tuple)):
|
if not isinstance(cls._meta.ordering, (list, tuple)):
|
||||||
|
@ -1502,9 +1512,6 @@ class Model(six.with_metaclass(ModelBase)):
|
||||||
# Convert "-field" to "field".
|
# Convert "-field" to "field".
|
||||||
fields = ((f[1:] if f.startswith('-') else f) for f in fields)
|
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
|
# Skip ordering in the format field1__field2 (FIXME: checking
|
||||||
# this format would be nice, but it's a little fiddly).
|
# this format would be nice, but it's a little fiddly).
|
||||||
fields = (f for f in fields if '__' not in f)
|
fields = (f for f in fields if '__' not in f)
|
||||||
|
|
|
@ -100,6 +100,7 @@ class Options(object):
|
||||||
self.verbose_name_plural = None
|
self.verbose_name_plural = None
|
||||||
self.db_table = ''
|
self.db_table = ''
|
||||||
self.ordering = []
|
self.ordering = []
|
||||||
|
self._ordering_clash = False
|
||||||
self.unique_together = []
|
self.unique_together = []
|
||||||
self.index_together = []
|
self.index_together = []
|
||||||
self.select_on_save = False
|
self.select_on_save = False
|
||||||
|
@ -234,6 +235,9 @@ class Options(object):
|
||||||
if self.verbose_name_plural is None:
|
if self.verbose_name_plural is None:
|
||||||
self.verbose_name_plural = string_concat(self.verbose_name, 's')
|
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.
|
# Any leftover attributes must be invalid.
|
||||||
if meta_attrs != {}:
|
if meta_attrs != {}:
|
||||||
raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()))
|
raise TypeError("'class Meta' got invalid attribute(s): %s" % ','.join(meta_attrs.keys()))
|
||||||
|
|
|
@ -63,6 +63,8 @@ Models
|
||||||
``<M2M field>``. Maximum length is ``<maximum length>`` for database
|
``<M2M field>``. Maximum length is ``<maximum length>`` for database
|
||||||
``<alias>``.
|
``<alias>``.
|
||||||
* **models.E020**: The ``<model>.check()`` class method is currently overridden.
|
* **models.E020**: The ``<model>.check()`` class method is currently overridden.
|
||||||
|
* **models.E021**: ``ordering`` and ``order_with_respect_to`` cannot be used
|
||||||
|
together.
|
||||||
|
|
||||||
Fields
|
Fields
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
|
@ -164,6 +164,9 @@ Models
|
||||||
<django.db.models.Model.delete>` to allow deleting only a child's data in a
|
<django.db.models.Model.delete>` to allow deleting only a child's data in a
|
||||||
model that uses multi-table inheritance.
|
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
|
CSRF
|
||||||
^^^^
|
^^^^
|
||||||
|
|
||||||
|
|
|
@ -566,6 +566,50 @@ class OtherModelTests(IsolatedModelsTestCase):
|
||||||
]
|
]
|
||||||
self.assertEqual(errors, expected)
|
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):
|
def test_non_valid(self):
|
||||||
class RelationModel(models.Model):
|
class RelationModel(models.Model):
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in New Issue