Loading django/db/models/base.py +3 −3 Original line number Diff line number Diff line Loading @@ -1674,13 +1674,13 @@ class Model(six.with_metaclass(ModelBase)): def method_set_order(ordered_obj, self, id_list, using=None): if using is None: using = DEFAULT_DB_ALIAS rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) order_name = ordered_obj._meta.order_with_respect_to.name order_wrt = ordered_obj._meta.order_with_respect_to filter_args = order_wrt.get_forward_related_filter(self) # FIXME: It would be nice if there was an "update many" version of update # for situations like this. with transaction.atomic(using=using, savepoint=False): for i, j in enumerate(id_list): ordered_obj.objects.filter(**{'pk': j, order_name: rel_val}).update(_order=i) ordered_obj.objects.filter(pk=j, **filter_args).update(_order=i) def method_get_order(ordered_obj, self): Loading django/db/models/fields/related.py +13 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,19 @@ class RelatedField(Field): else: self.do_related_class(other, cls) def get_forward_related_filter(self, obj): """ Return the keyword arguments that when supplied to self.model.object.filter(), would select all instances related through this field to the remote obj. This is used to build the querysets returned by related descriptors. obj is an instance of self.related_field.model. """ return { '%s__%s' % (self.name, rh_field.name): getattr(obj, rh_field.attname) for _, rh_field in self.related_fields } @property def swappable_setting(self): """ Loading docs/releases/1.8.7.txt +4 −0 Original line number Diff line number Diff line Loading @@ -42,3 +42,7 @@ Bugfixes * Fixed a duplicate query regression in 1.8 on proxied model deletion (:ticket:`25685`). * Fixed ``set_FOO_order()`` crash when the ``ForeignKey`` of a model with ``order_with_respect_to`` references a model with a ``OneToOneField`` primary key (:ticket:`25786`). tests/order_with_respect_to/models.py +16 −0 Original line number Diff line number Diff line Loading @@ -33,3 +33,19 @@ class Post(models.Model): def __str__(self): return self.title # order_with_respect_to points to a model with a OneToOneField primary key. class Entity(models.Model): pass class Dimension(models.Model): entity = models.OneToOneField('Entity', primary_key=True) class Component(models.Model): dimension = models.ForeignKey('Dimension') class Meta: order_with_respect_to = 'dimension' tests/order_with_respect_to/tests.py +11 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ from operator import attrgetter from django.db import models from django.test import TestCase from .models import Answer, Post, Question from .models import Answer, Dimension, Entity, Post, Question class OrderWithRespectToTests(TestCase): Loading Loading @@ -103,3 +103,13 @@ class OrderWithRespectToTests2(TestCase): count += 1 self.assertEqual(count, 1) class TestOrderWithRespectToOneToOnePK(TestCase): def test_set_order(self): e = Entity.objects.create() d = Dimension.objects.create(entity=e) c1 = d.component_set.create() c2 = d.component_set.create() d.set_component_order([c1.id, c2.id]) self.assertQuerysetEqual(d.component_set.all(), [c1.id, c2.id], attrgetter('pk')) Loading
django/db/models/base.py +3 −3 Original line number Diff line number Diff line Loading @@ -1674,13 +1674,13 @@ class Model(six.with_metaclass(ModelBase)): def method_set_order(ordered_obj, self, id_list, using=None): if using is None: using = DEFAULT_DB_ALIAS rel_val = getattr(self, ordered_obj._meta.order_with_respect_to.rel.field_name) order_name = ordered_obj._meta.order_with_respect_to.name order_wrt = ordered_obj._meta.order_with_respect_to filter_args = order_wrt.get_forward_related_filter(self) # FIXME: It would be nice if there was an "update many" version of update # for situations like this. with transaction.atomic(using=using, savepoint=False): for i, j in enumerate(id_list): ordered_obj.objects.filter(**{'pk': j, order_name: rel_val}).update(_order=i) ordered_obj.objects.filter(pk=j, **filter_args).update(_order=i) def method_get_order(ordered_obj, self): Loading
django/db/models/fields/related.py +13 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,19 @@ class RelatedField(Field): else: self.do_related_class(other, cls) def get_forward_related_filter(self, obj): """ Return the keyword arguments that when supplied to self.model.object.filter(), would select all instances related through this field to the remote obj. This is used to build the querysets returned by related descriptors. obj is an instance of self.related_field.model. """ return { '%s__%s' % (self.name, rh_field.name): getattr(obj, rh_field.attname) for _, rh_field in self.related_fields } @property def swappable_setting(self): """ Loading
docs/releases/1.8.7.txt +4 −0 Original line number Diff line number Diff line Loading @@ -42,3 +42,7 @@ Bugfixes * Fixed a duplicate query regression in 1.8 on proxied model deletion (:ticket:`25685`). * Fixed ``set_FOO_order()`` crash when the ``ForeignKey`` of a model with ``order_with_respect_to`` references a model with a ``OneToOneField`` primary key (:ticket:`25786`).
tests/order_with_respect_to/models.py +16 −0 Original line number Diff line number Diff line Loading @@ -33,3 +33,19 @@ class Post(models.Model): def __str__(self): return self.title # order_with_respect_to points to a model with a OneToOneField primary key. class Entity(models.Model): pass class Dimension(models.Model): entity = models.OneToOneField('Entity', primary_key=True) class Component(models.Model): dimension = models.ForeignKey('Dimension') class Meta: order_with_respect_to = 'dimension'
tests/order_with_respect_to/tests.py +11 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,7 @@ from operator import attrgetter from django.db import models from django.test import TestCase from .models import Answer, Post, Question from .models import Answer, Dimension, Entity, Post, Question class OrderWithRespectToTests(TestCase): Loading Loading @@ -103,3 +103,13 @@ class OrderWithRespectToTests2(TestCase): count += 1 self.assertEqual(count, 1) class TestOrderWithRespectToOneToOnePK(TestCase): def test_set_order(self): e = Entity.objects.create() d = Dimension.objects.create(entity=e) c1 = d.component_set.create() c2 = d.component_set.create() d.set_component_order([c1.id, c2.id]) self.assertQuerysetEqual(d.component_set.all(), [c1.id, c2.id], attrgetter('pk'))