Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[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
  • Loading branch information...
commit 8092c67d51668c616ad3352ad269eafe75a98fb0 1 parent a827ba7
Russell Keith-Magee freakboy3742 authored
14 django/db/models/fields/related.py
View
@@ -132,12 +132,13 @@ def pk_trace(value):
v, field = getattr(v, v._meta.pk.name), v._meta.pk
except AttributeError:
pass
- if field:
- if lookup_type in ('range', 'in'):
- v = [v]
- v = field.get_db_prep_lookup(lookup_type, v)
- if isinstance(v, list):
- v = v[0]
+ 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)
+ if isinstance(v, list):
+ v = v[0]
return v
if hasattr(value, 'as_sql'):
@@ -953,4 +954,3 @@ def db_type(self):
# A ManyToManyField is not represented by a single column,
# so return None.
return None
-
54 tests/modeltests/custom_pk/fields.py
View
@@ -0,0 +1,54 @@
+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 tests/modeltests/custom_pk/models.py
View
@@ -9,6 +9,8 @@
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 Meta:
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 @@ def __unicode__(self):
... 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
Please sign in to comment.
Something went wrong with that request. Please try again.