Commit 131d83b9 authored by Carl Meyer's avatar Carl Meyer
Browse files

[1.2.X] Fixed #11319 - Added lookup support for ForeignKey.to_field. Also...

[1.2.X] Fixed #11319 - Added lookup support for ForeignKey.to_field. Also reverted no-longer-needed model formsets workaround for lack of such support from r10756. Thanks Russell and Alex for review.

Backport of r15303 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15304 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent f01e1cd4
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -176,9 +176,20 @@ class RelatedField(object):
        # the primary key may itself be an object - so we need to keep drilling
        # down until we hit a value that can be used for a comparison.
        v = value

        # In the case of an FK to 'self', this check allows to_field to be used
        # for both forwards and reverse lookups across the FK. (For normal FKs,
        # it's only relevant for forward lookups).
        if isinstance(v, self.rel.to):
            field_name = getattr(self.rel, "field_name", None)
        else:
            field_name = None
        try:
            while True:
                v = getattr(v, v._meta.pk.name)
                if field_name is None:
                    field_name = v._meta.pk.name
                v = getattr(v, field_name)
                field_name = None
        except AttributeError:
            pass
        except exceptions.ObjectDoesNotExist:
+6 −1
Original line number Diff line number Diff line
@@ -1365,6 +1365,11 @@ class Query(object):
                        table = opts.db_table
                        from_col = local_field.column
                        to_col = field.column
                        # In case of a recursive FK, use the to_field for
                        # reverse lookups as well
                        if orig_field.model is local_field.model:
                            target = opts.get_field(field.rel.field_name)
                        else:
                            target = opts.pk
                        orig_opts._join_cache[name] = (table, from_col, to_col,
                                opts, target)
+1 −5
Original line number Diff line number Diff line
@@ -690,13 +690,9 @@ class BaseInlineFormSet(BaseModelFormSet):
        self.save_as_new = save_as_new
        # is there a better way to get the object descriptor?
        self.rel_name = RelatedObject(self.fk.rel.to, self.model, self.fk).get_accessor_name()
        if self.fk.rel.field_name == self.fk.rel.to._meta.pk.name:
            backlink_value = self.instance
        else:
            backlink_value = getattr(self.instance, self.fk.rel.field_name)
        if queryset is None:
            queryset = self.model._default_manager
        qs = queryset.filter(**{self.fk.name: backlink_value})
        qs = queryset.filter(**{self.fk.name: self.instance})
        super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix,
                                                queryset=qs)

+3 −5
Original line number Diff line number Diff line
@@ -158,11 +158,9 @@ class CustomPKTests(TestCase):
        new_bar = Bar.objects.create()
        new_foo = Foo.objects.create(bar=new_bar)

        # FIXME: This still doesn't work, but will require some changes in
        # get_db_prep_lookup to fix it.
        # f = Foo.objects.get(bar=new_bar.pk)
        # self.assertEqual(f, new_foo)
        # self.assertEqual(f.bar, new_bar)
        f = Foo.objects.get(bar=new_bar.pk)
        self.assertEqual(f, new_foo)
        self.assertEqual(f.bar, new_bar)

        f = Foo.objects.get(bar=new_bar)
        self.assertEqual(f, new_foo),
+20 −0
Original line number Diff line number Diff line
@@ -274,3 +274,23 @@ class Plaything(models.Model):
class Article(models.Model):
    name = models.CharField(max_length=20)
    created = models.DateTimeField()

class Food(models.Model):
    name = models.CharField(max_length=20, unique=True)

    def __unicode__(self):
        return self.name

class Eaten(models.Model):
    food = models.ForeignKey(Food, to_field="name")
    meal = models.CharField(max_length=20)

    def __unicode__(self):
        return u"%s at %s" % (self.food, self.meal)

class Node(models.Model):
    num = models.IntegerField(unique=True)
    parent = models.ForeignKey("self", to_field="num", null=True)

    def __unicode__(self):
        return u"%s" % self.num
Loading