Commit 8092c67d authored by Russell Keith-Magee's avatar Russell Keith-Magee
Browse files

[1.0.X] Fixed #10785 -- Corrected a case for foreign key lookup where the...

[1.0.X] Fixed #10785 -- Corrected a case for foreign key lookup where the related object is a custom primary key. Thanks to Alex Gaynor for the patch.

Merge of r10952 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10953 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent a827ba72
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -132,7 +132,8 @@ class RelatedField(object):
                    v, field = getattr(v, v._meta.pk.name), v._meta.pk
            except AttributeError:
                pass
            if field:
            if not field:
                field = self.rel.get_related_field()
            if lookup_type in ('range', 'in'):
                v = [v]
            v = field.get_db_prep_lookup(lookup_type, v)
@@ -953,4 +954,3 @@ class ManyToManyField(RelatedField, Field):
        # A ManyToManyField is not represented by a single column,
        # so return None.
        return None
+54 −0
Original line number Diff line number Diff line
import random
import string

from django.db import models

class MyWrapper(object):
    def __init__(self, value):
        self.value = value

    def __repr__(self):
        return "<%s: %s>" % (self.__class__.__name__, self.value)

    def __unicode__(self):
        return self.value

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.value == other.value
        return self.value == other

class MyAutoField(models.CharField):
    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 10
        super(MyAutoField, self).__init__(*args, **kwargs)

    def pre_save(self, instance, add):
        value = getattr(instance, self.attname, None)
        if not value:
            value = MyWrapper(''.join(random.sample(string.lowercase, 10)))
            setattr(instance, self.attname, value)
        return value

    def to_python(self, value):
        if not value:
            return
        if not isinstance(value, MyWrapper):
            value = MyWrapper(value)
        return value

    def get_db_prep_save(self, value):
        if not value:
            return
        if isinstance(value, MyWrapper):
            return unicode(value)
        return value

    def get_db_prep_value(self, value):
        if not value:
            return
        if isinstance(value, MyWrapper):
            return unicode(value)
        return value
+27 −0
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@ this behavior by explicitly adding ``primary_key=True`` to a field.
from django.conf import settings
from django.db import models, transaction, IntegrityError

from fields import MyAutoField

class Employee(models.Model):
    employee_code = models.IntegerField(primary_key=True, db_column = 'code')
    first_name = models.CharField(max_length=20)
@@ -28,6 +30,16 @@ class Business(models.Model):
    def __unicode__(self):
        return self.name

class Bar(models.Model):
    id = MyAutoField(primary_key=True, db_index=True)

    def __unicode__(self):
        return repr(self.pk)


class Foo(models.Model):
    bar = models.ForeignKey(Bar)

__test__ = {'API_TESTS':"""
>>> dan = Employee(employee_code=123, first_name='Dan', last_name='Jones')
>>> dan.save()
@@ -121,6 +133,21 @@ DoesNotExist: Employee matching query does not exist.
...        print "Fail with %s" % type(e)
Pass

# Regression for #10785 -- Custom fields can be used for primary keys.
>>> new_bar = Bar.objects.create()
>>> new_foo = Foo.objects.create(bar=new_bar)
>>> f = Foo.objects.get(bar=new_bar.pk)
>>> f == new_foo
True
>>> f.bar == new_bar
True

>>> f = Foo.objects.get(bar=new_bar)
>>> f == new_foo
True
>>> f.bar == new_bar
True

"""}

# SQLite lets objects be saved with an empty primary key, even though an