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.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10952 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
89df572c47
commit
6cd37e0a1f
|
@ -132,7 +132,8 @@ class RelatedField(object):
|
||||||
v, field = getattr(v, v._meta.pk.name), v._meta.pk
|
v, field = getattr(v, v._meta.pk.name), v._meta.pk
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
if field:
|
if not field:
|
||||||
|
field = self.rel.get_related_field()
|
||||||
if lookup_type in ('range', 'in'):
|
if lookup_type in ('range', 'in'):
|
||||||
v = [v]
|
v = [v]
|
||||||
v = field.get_db_prep_lookup(lookup_type, v)
|
v = field.get_db_prep_lookup(lookup_type, v)
|
||||||
|
@ -958,4 +959,3 @@ class ManyToManyField(RelatedField, Field):
|
||||||
# A ManyToManyField is not represented by a single column,
|
# A ManyToManyField is not represented by a single column,
|
||||||
# so return None.
|
# so return None.
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -9,6 +9,8 @@ this behavior by explicitly adding ``primary_key=True`` to a field.
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db import models, transaction, IntegrityError
|
from django.db import models, transaction, IntegrityError
|
||||||
|
|
||||||
|
from fields import MyAutoField
|
||||||
|
|
||||||
class Employee(models.Model):
|
class Employee(models.Model):
|
||||||
employee_code = models.IntegerField(primary_key=True, db_column = 'code')
|
employee_code = models.IntegerField(primary_key=True, db_column = 'code')
|
||||||
first_name = models.CharField(max_length=20)
|
first_name = models.CharField(max_length=20)
|
||||||
|
@ -28,6 +30,16 @@ class Business(models.Model):
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.name
|
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':"""
|
__test__ = {'API_TESTS':"""
|
||||||
>>> dan = Employee(employee_code=123, first_name='Dan', last_name='Jones')
|
>>> dan = Employee(employee_code=123, first_name='Dan', last_name='Jones')
|
||||||
>>> dan.save()
|
>>> dan.save()
|
||||||
|
@ -121,6 +133,21 @@ DoesNotExist: Employee matching query does not exist.
|
||||||
... print "Fail with %s" % type(e)
|
... print "Fail with %s" % type(e)
|
||||||
Pass
|
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
|
# SQLite lets objects be saved with an empty primary key, even though an
|
||||||
|
|
Loading…
Reference in New Issue