mirror of https://github.com/django/django.git
[3.0.x] Fixed #13296 -- Fixed ordering by Options.order_with_respect_to after deleting objects.
Thanks Simon Meers for the original patch.
Backport of f97bbad908
from master
This commit is contained in:
parent
368832e803
commit
2362f27265
|
@ -15,13 +15,16 @@ from django.db import (
|
||||||
DEFAULT_DB_ALIAS, DJANGO_VERSION_PICKLE_KEY, DatabaseError, connection,
|
DEFAULT_DB_ALIAS, DJANGO_VERSION_PICKLE_KEY, DatabaseError, connection,
|
||||||
connections, router, transaction,
|
connections, router, transaction,
|
||||||
)
|
)
|
||||||
from django.db.models import NOT_PROVIDED
|
from django.db.models import (
|
||||||
|
NOT_PROVIDED, ExpressionWrapper, IntegerField, Max, Value,
|
||||||
|
)
|
||||||
from django.db.models.constants import LOOKUP_SEP
|
from django.db.models.constants import LOOKUP_SEP
|
||||||
from django.db.models.constraints import CheckConstraint, UniqueConstraint
|
from django.db.models.constraints import CheckConstraint, UniqueConstraint
|
||||||
from django.db.models.deletion import CASCADE, Collector
|
from django.db.models.deletion import CASCADE, Collector
|
||||||
from django.db.models.fields.related import (
|
from django.db.models.fields.related import (
|
||||||
ForeignObjectRel, OneToOneField, lazy_related_operation, resolve_relation,
|
ForeignObjectRel, OneToOneField, lazy_related_operation, resolve_relation,
|
||||||
)
|
)
|
||||||
|
from django.db.models.functions import Coalesce
|
||||||
from django.db.models.manager import Manager
|
from django.db.models.manager import Manager
|
||||||
from django.db.models.options import Options
|
from django.db.models.options import Options
|
||||||
from django.db.models.query import Q
|
from django.db.models.query import Q
|
||||||
|
@ -869,9 +872,12 @@ class Model(metaclass=ModelBase):
|
||||||
# autopopulate the _order field
|
# autopopulate the _order field
|
||||||
field = meta.order_with_respect_to
|
field = meta.order_with_respect_to
|
||||||
filter_args = field.get_filter_kwargs_for_object(self)
|
filter_args = field.get_filter_kwargs_for_object(self)
|
||||||
order_value = cls._base_manager.using(using).filter(**filter_args).count()
|
self._order = cls._base_manager.using(using).filter(**filter_args).aggregate(
|
||||||
self._order = order_value
|
_order__max=Coalesce(
|
||||||
|
ExpressionWrapper(Max('_order') + Value(1), output_field=IntegerField()),
|
||||||
|
Value(0),
|
||||||
|
),
|
||||||
|
)['_order__max']
|
||||||
fields = meta.local_concrete_fields
|
fields = meta.local_concrete_fields
|
||||||
if not pk_set:
|
if not pk_set:
|
||||||
fields = [f for f in fields if f is not meta.auto_field]
|
fields = [f for f in fields if f is not meta.auto_field]
|
||||||
|
|
|
@ -87,3 +87,17 @@ class BaseOrderWithRespectToTests:
|
||||||
self.Post.objects.create(title="2.1", parent=p2)
|
self.Post.objects.create(title="2.1", parent=p2)
|
||||||
p1_3 = self.Post.objects.create(title="1.3", parent=p1)
|
p1_3 = self.Post.objects.create(title="1.3", parent=p1)
|
||||||
self.assertSequenceEqual(p1.get_post_order(), [p1_1.pk, p1_2.pk, p1_3.pk])
|
self.assertSequenceEqual(p1.get_post_order(), [p1_1.pk, p1_2.pk, p1_3.pk])
|
||||||
|
|
||||||
|
def test_delete_and_insert(self):
|
||||||
|
q1 = self.Question.objects.create(text='What is your favorite color?')
|
||||||
|
q2 = self.Question.objects.create(text='What color is it?')
|
||||||
|
a1 = self.Answer.objects.create(text='Blue', question=q1)
|
||||||
|
a2 = self.Answer.objects.create(text='Red', question=q1)
|
||||||
|
a3 = self.Answer.objects.create(text='Green', question=q1)
|
||||||
|
a4 = self.Answer.objects.create(text='Yellow', question=q1)
|
||||||
|
self.assertSequenceEqual(q1.answer_set.all(), [a1, a2, a3, a4])
|
||||||
|
a3.question = q2
|
||||||
|
a3.save()
|
||||||
|
a1.delete()
|
||||||
|
new_answer = self.Answer.objects.create(text='Black', question=q1)
|
||||||
|
self.assertSequenceEqual(q1.answer_set.all(), [a2, a4, new_answer])
|
||||||
|
|
Loading…
Reference in New Issue