Code

Ticket #10785: custom_pk.2.diff

File custom_pk.2.diff, 5.3 KB (added by Alex, 5 years ago)
Line 
1diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
2index 1d083cd..586d80c 100644
3--- a/django/db/models/fields/related.py
4+++ b/django/db/models/fields/related.py
5@@ -132,12 +132,13 @@ class RelatedField(object):
6                     v, field = getattr(v, v._meta.pk.name), v._meta.pk
7             except AttributeError:
8                 pass
9-            if field:
10-                if lookup_type in ('range', 'in'):
11-                    v = [v]
12-                v = field.get_db_prep_lookup(lookup_type, v)
13-                if isinstance(v, list):
14-                    v = v[0]
15+            if not field:
16+                field = self.rel.get_related_field()
17+            if lookup_type in ('range', 'in'):
18+                v = [v]
19+            v = field.get_db_prep_lookup(lookup_type, v)
20+            if isinstance(v, list):
21+                v = v[0]
22             return v
23 
24         if hasattr(value, 'as_sql') or hasattr(value, '_as_sql'):
25@@ -955,4 +956,3 @@ class ManyToManyField(RelatedField, Field):
26         # A ManyToManyField is not represented by a single column,
27         # so return None.
28         return None
29-
30diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
31index ec0545c..0379aed 100644
32--- a/django/db/models/sql/where.py
33+++ b/django/db/models/sql/where.py
34@@ -278,4 +278,3 @@ class Constraint(object):
35             raise EmptyShortCircuit
36 
37         return (self.alias, self.col, db_type), params
38-
39diff --git a/tests/modeltests/custom_pk/fields.py b/tests/modeltests/custom_pk/fields.py
40new file mode 100644
41index 0000000..319e42f
42--- /dev/null
43+++ b/tests/modeltests/custom_pk/fields.py
44@@ -0,0 +1,54 @@
45+import random
46+import string
47+
48+from django.db import models
49+
50+class MyWrapper(object):
51+    def __init__(self, value):
52+        self.value = value
53+
54+    def __repr__(self):
55+        return "<%s: %s>" % (self.__class__.__name__, self.value)
56+
57+    def __unicode__(self):
58+        return self.value
59+
60+    def __eq__(self, other):
61+        if isinstance(other, self.__class__):
62+            return self.value == other.value
63+        return self.value == other
64+
65+class MyAutoField(models.CharField):
66+    __metaclass__ = models.SubfieldBase
67+
68+    def __init__(self, *args, **kwargs):
69+        kwargs['max_length'] = 10
70+        super(MyAutoField, self).__init__(*args, **kwargs)
71+
72+    def pre_save(self, instance, add):
73+        value = getattr(instance, self.attname, None)
74+        if not value:
75+            value = MyWrapper(''.join(random.sample(string.lowercase, 10)))
76+            setattr(instance, self.attname, value)
77+        return value
78+
79+    def to_python(self, value):
80+        if not value:
81+            return
82+        if not isinstance(value, MyWrapper):
83+            value = MyWrapper(value)
84+        return value
85+
86+    def get_db_prep_save(self, value):
87+        if not value:
88+            return
89+        if isinstance(value, MyWrapper):
90+            return unicode(value)
91+        return value
92+
93+    def get_db_prep_value(self, value):
94+        if not value:
95+            return
96+        if isinstance(value, MyWrapper):
97+            return unicode(value)
98+        return value
99diff --git a/tests/modeltests/custom_pk/models.py b/tests/modeltests/custom_pk/models.py
100index 091f7f3..0323fec 100644
101--- a/tests/modeltests/custom_pk/models.py
102+++ b/tests/modeltests/custom_pk/models.py
103@@ -9,6 +9,8 @@ this behavior by explicitly adding ``primary_key=True`` to a field.
104 from django.conf import settings
105 from django.db import models, transaction, IntegrityError
106 
107+from fields import MyAutoField
108+
109 class Employee(models.Model):
110     employee_code = models.IntegerField(primary_key=True, db_column = 'code')
111     first_name = models.CharField(max_length=20)
112@@ -28,6 +30,16 @@ class Business(models.Model):
113     def __unicode__(self):
114         return self.name
115 
116+class Bar(models.Model):
117+    id = MyAutoField(primary_key=True, db_index=True)
118+
119+    def __unicode__(self):
120+        return repr(self.pk)
121+
122+
123+class Foo(models.Model):
124+    bar = models.ForeignKey(Bar)
125+
126 __test__ = {'API_TESTS':"""
127 >>> dan = Employee(employee_code=123, first_name='Dan', last_name='Jones')
128 >>> dan.save()
129@@ -121,6 +133,13 @@ DoesNotExist: Employee matching query does not exist.
130 ...        print "Fail with %s" % type(e)
131 Pass
132 
133+>>> new_bar = Bar.objects.create()
134+>>> new_foo = Foo.objects.create(bar=new_bar)
135+>>> f = Foo.objects.get(bar=new_bar.pk)
136+>>> f == new_foo
137+True
138+>>> f.bar == new_bar
139+True
140 """}
141 
142 # SQLite lets objects be saved with an empty primary key, even though an
143diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py
144index 992bb90..295c557 100644
145--- a/tests/modeltests/model_forms/models.py
146+++ b/tests/modeltests/model_forms/models.py
147@@ -189,6 +189,8 @@ class ExplicitPK(models.Model):
148     def __unicode__(self):
149         return self.key
150 
151+
152+
153 __test__ = {'API_TESTS': """
154 >>> from django import forms
155 >>> from django.forms.models import ModelForm, model_to_dict
156@@ -1472,6 +1474,7 @@ ValidationError: [u'Select a valid choice. z is not one of the available choices
157 <tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr>
158 <tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr>
159 
160+
161 # Clean up
162 >>> import shutil
163 >>> shutil.rmtree(temp_storage_dir)