diff options
| author | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-06-29 10:35:35 +0000 |
|---|---|---|
| committer | Malcolm Tredinnick <malcolm.tredinnick@gmail.com> | 2008-06-29 10:35:35 +0000 |
| commit | c17e3265852722d572614b96b8bda1105ee8352e (patch) | |
| tree | 2eb71de26c30ddb543c19bebbe0713a5b05b50b6 | |
| parent | 493163963633e9746a1eaf84bc39c574e4432eb2 (diff) | |
Fixed #7378 -- Use the "to_field" where appropriate on reverse relations.
Patch from mturtle@gmail.com. The remaining uses of "%s__pk" in
fields/related.py all look safe, since they are for many-to-many fields, which
doesn't take "to_field" as a parameter.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@7785 bcc190cf-cafb-0310-a4f2-bffc1f526a37
| -rw-r--r-- | django/db/models/fields/related.py | 24 | ||||
| -rw-r--r-- | tests/regressiontests/queries/models.py | 8 |
2 files changed, 19 insertions, 13 deletions
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index a8d402dcfd..a1977c07b4 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -185,11 +185,11 @@ class SingleRelatedObjectDescriptor(object): def __set__(self, instance, value): if instance is None: raise AttributeError, "%s must be accessed via instance" % self.related.opts.object_name - - # The similarity of the code below to the code in + + # The similarity of the code below to the code in # ReverseSingleRelatedObjectDescriptor is annoying, but there's a bunch # of small differences that would make a common base class convoluted. - + # If null=True, we can assign null here, but otherwise the value needs # to be an instance of the related class. if value is None and self.related.field.null == False: @@ -197,14 +197,14 @@ class SingleRelatedObjectDescriptor(object): (instance._meta.object_name, self.related.get_accessor_name())) elif value is not None and not isinstance(value, self.related.model): raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' % - (value, instance._meta.object_name, + (value, instance._meta.object_name, self.related.get_accessor_name(), self.related.opts.object_name)) - + # Set the value of the related field setattr(value, self.related.field.rel.get_related_field().attname, instance) # Since we already know what the related object is, seed the related - # object caches now, too. This avoids another db hit if you get the + # object caches now, too. This avoids another db hit if you get the # object you just set. setattr(instance, self.cache_name, value) setattr(value, self.related.field.get_cache_name(), instance) @@ -243,7 +243,7 @@ class ReverseSingleRelatedObjectDescriptor(object): def __set__(self, instance, value): if instance is None: raise AttributeError, "%s must be accessed via instance" % self._field.name - + # If null=True, we can assign null here, but otherwise the value needs # to be an instance of the related class. if value is None and self.field.null == False: @@ -251,9 +251,9 @@ class ReverseSingleRelatedObjectDescriptor(object): (instance._meta.object_name, self.field.name)) elif value is not None and not isinstance(value, self.field.rel.to): raise ValueError('Cannot assign "%r": "%s.%s" must be a "%s" instance.' % - (value, instance._meta.object_name, + (value, instance._meta.object_name, self.field.name, self.field.rel.to._meta.object_name)) - + # Set the value of the related field try: val = getattr(value, self.field.rel.get_related_field().attname) @@ -262,7 +262,7 @@ class ReverseSingleRelatedObjectDescriptor(object): setattr(instance, self.field.attname, val) # Since we already know what the related object is, seed the related - # object cache now, too. This avoids another db hit if you get the + # object cache now, too. This avoids another db hit if you get the # object you just set. setattr(instance, self.field.get_cache_name(), value) @@ -322,7 +322,9 @@ class ForeignRelatedObjectsDescriptor(object): clear.alters_data = True manager = RelatedManager() - manager.core_filters = {'%s__pk' % rel_field.name: getattr(instance, rel_field.rel.get_related_field().attname)} + attname = rel_field.rel.get_related_field().name + manager.core_filters = {'%s__%s' % (rel_field.name, attname): + getattr(instance, attname)} manager.model = self.related.model return manager diff --git a/tests/regressiontests/queries/models.py b/tests/regressiontests/queries/models.py index 202b61647a..d7938f63a9 100644 --- a/tests/regressiontests/queries/models.py +++ b/tests/regressiontests/queries/models.py @@ -368,6 +368,10 @@ Bug #4510 >>> Author.objects.filter(report__name='r1') [<Author: a1>] +Bug #7378 +>>> a1.report_set.all() +[<Report: r1>] + Bug #5324, #6704 >>> Item.objects.filter(tags__name='t4') [<Item: four>] @@ -777,8 +781,8 @@ this doesn't crash, it's a Good Thing. >>> out = pickle.dumps(Item.objects.all()) Bug #7277 ->>> a1 = Annotation.objects.create(name='a1', tag=t1) ->>> a1.notes.add(n1) +>>> ann1 = Annotation.objects.create(name='a1', tag=t1) +>>> ann1.notes.add(n1) >>> n1.annotation_set.filter(Q(tag=t5) | Q(tag__children=t5) | Q(tag__children__children=t5)) [<Annotation: a1>] |
