Ticket #13296: 13296.diff
File 13296.diff, 5.6 KB (added by , 13 years ago) |
---|
-
django/db/models/base.py
diff -r 548df236b2cc django/db/models/base.py
a b 17 17 from django.db.models.query_utils import DeferredAttribute 18 18 from django.db.models.deletion import Collector 19 19 from django.db.models.options import Options 20 from django.db.models.aggregates import Max 20 21 from django.db.models import signals 21 22 from django.db.models.loading import register_models, get_model 22 23 from django.utils.translation import ugettext_lazy as _ … … 24 25 from django.utils.encoding import smart_str, force_unicode 25 26 from django.utils.text import get_text_list, capfirst 26 27 27 28 28 class ModelBase(type): 29 29 """ 30 30 Metaclass for all models. … … 229 229 opts._prepare(cls) 230 230 231 231 if opts.order_with_respect_to: 232 cls.get_next_in_order = curry(cls._get_next_or_previous_in_order, is_next=True) 233 cls.get_previous_in_order = curry(cls._get_next_or_previous_in_order, is_next=False) 232 cls.get_next_in_order = curry( 233 cls._get_next_or_previous_in_order, is_next=True) 234 cls.get_previous_in_order = curry( 235 cls._get_next_or_previous_in_order, is_next=False) 234 236 # defer creating accessors on the foreign class until we are 235 237 # certain it has been created 236 238 def make_foreign_order_accessors(field, model, cls): … … 537 539 # If this is a model with an order_with_respect_to 538 540 # autopopulate the _order field 539 541 field = meta.order_with_respect_to 540 order_value = manager.using(using).filter(**{field.name: getattr(self, field.attname)}).count() 541 self._order = order_value 542 max_order_value = manager.using(using).filter( 543 **{field.name: getattr(self, field.attname)}).aggregate( 544 Max('_order'))['_order__max'] 545 self._order = (max_order_value or 0) + 1 542 546 543 547 if not pk_set: 544 548 if force_update: -
tests/modeltests/order_with_respect_to/tests.py
diff -r 548df236b2cc tests/modeltests/order_with_respect_to/tests.py
a b 2 2 3 3 from django.test import TestCase 4 4 5 from models import Post, Question, Answer5 from .models import Post, Question, Answer 6 6 7 7 8 8 class OrderWithRespectToTests(TestCase): 9 9 def test_basic(self): 10 10 q1 = Question.objects.create(text="Which Beatle starts with the letter 'R'?") 11 11 q2 = Question.objects.create(text="What is your name?") 12 12 13 13 Answer.objects.create(text="John", question=q1) 14 14 Answer.objects.create(text="Jonno", question=q2) 15 15 Answer.objects.create(text="Paul", question=q1) 16 16 Answer.objects.create(text="Paulo", question=q2) 17 17 Answer.objects.create(text="George", question=q1) 18 18 Answer.objects.create(text="Ringo", question=q1) 19 19 20 20 # The answers will always be ordered in the order they were inserted. 21 21 self.assertQuerysetEqual( 22 22 q1.answer_set.all(), [ … … 24 24 ], 25 25 attrgetter("text"), 26 26 ) 27 27 28 28 # We can retrieve the answers related to a particular object, in the 29 29 # order they were created, once we have a particular object. 30 30 a1 = Answer.objects.filter(question=q1)[0] … … 34 34 a4 = list(Answer.objects.filter(question=q1))[-1] 35 35 self.assertEqual(a4.text, "Ringo") 36 36 self.assertEqual(a4.get_previous_in_order().text, "George") 37 37 38 38 # Determining (and setting) the ordering for a particular item is also 39 39 # possible. 40 40 id_list = [o.pk for o in q1.answer_set.all()] 41 41 self.assertEqual(a2.question.get_answer_order(), id_list) 42 42 43 43 a5 = Answer.objects.create(text="Number five", question=q1) 44 44 45 45 # It doesn't matter which answer we use to check the order, it will 46 46 # always be the same. 47 47 self.assertEqual( 48 48 a2.question.get_answer_order(), a5.question.get_answer_order() 49 49 ) 50 50 51 51 # The ordering can be altered: 52 52 id_list = [o.pk for o in q1.answer_set.all()] 53 53 x = id_list.pop() … … 69 69 p2_1 = Post.objects.create(title="2.1", parent=p2) 70 70 p1_3 = Post.objects.create(title="1.3", parent=p1) 71 71 self.assertEqual(p1.get_post_order(), [p1_1.pk, p1_2.pk, p1_3.pk]) 72 73 def test_deletion_and_insertion(self): 74 """ Regression test for https://code.djangoproject.com/ticket/13296 """ 75 q1 = Question.objects.create(text="Which Beatle starts with the letter 'R'?") 76 q2 = Question.objects.create(text="What is your name?") 77 a1 = Answer.objects.create(text="John", question=q1) 78 a2 = Answer.objects.create(text="Paul", question=q1) 79 a3 = Answer.objects.create(text="George", question=q1) 80 a4 = Answer.objects.create(text="Ringo", question=q1) 81 self.assertQuerysetEqual( 82 q1.answer_set.all(), ["John", "Paul", "George", "Ringo",], 83 attrgetter("text")) 84 85 # delete/move some entries 86 a2.delete() 87 a3.question = q2 88 a3.save() 89 self.assertQuerysetEqual( 90 q1.answer_set.all(), ["John", "Ringo",], attrgetter("text")) 91 92 # insert a new one and see if it lands at the end 93 a5 = Answer.objects.create(text="Guido", question=q1) 94 self.assertQuerysetEqual( 95 q1.answer_set.all(), ["John", "Ringo", "Guido"], attrgetter("text"))