Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Allow for matches against unsaved objects in querysets (which will th…

…erefore

match nothing). This allows for some more straightforward code in the admin
interface.

Fixed #7488 (all the debugging there was done by Brian Rosner, who narrowed it
down to the item in this patch).


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8061 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit a7b556ca044b2d51d25d566a7ce6410111cf50e1 1 parent 3912403
Malcolm Tredinnick authored July 23, 2008
39  django/db/models/sql/where.py
@@ -35,20 +35,30 @@ def add(self, data, connector):
35 35
         storing any reference to field objects). Otherwise, the 'data' is
36 36
         stored unchanged and can be anything with an 'as_sql()' method.
37 37
         """
  38
+        # Because of circular imports, we need to import this here.
  39
+        from django.db.models.base import ObjectDoesNotExist
  40
+
38 41
         if not isinstance(data, (list, tuple)):
39 42
             super(WhereNode, self).add(data, connector)
40 43
             return
41 44
 
42 45
         alias, col, field, lookup_type, value = data
43  
-        if field:
44  
-            params = field.get_db_prep_lookup(lookup_type, value)
45  
-            db_type = field.db_type()
46  
-        else:
47  
-            # This is possible when we add a comparison to NULL sometimes (we
48  
-            # don't really need to waste time looking up the associated field
49  
-            # object).
50  
-            params = Field().get_db_prep_lookup(lookup_type, value)
51  
-            db_type = None
  46
+        try:
  47
+            if field:
  48
+                params = field.get_db_prep_lookup(lookup_type, value)
  49
+                db_type = field.db_type()
  50
+            else:
  51
+                # This is possible when we add a comparison to NULL sometimes
  52
+                # (we don't really need to waste time looking up the associated
  53
+                # field object).
  54
+                params = Field().get_db_prep_lookup(lookup_type, value)
  55
+                db_type = None
  56
+        except ObjectDoesNotExist:
  57
+            # This can happen when trying to insert a reference to a null pk.
  58
+            # We break out of the normal path and indicate there's nothing to
  59
+            # match.
  60
+            super(WhereNode, self).add(NothingNode(), connector)
  61
+            return
52 62
         if isinstance(value, datetime.datetime):
53 63
             annotation = datetime.datetime
54 64
         else:
@@ -190,3 +200,14 @@ def as_sql(self, qn=None):
190 200
 
191 201
     def relabel_aliases(self, change_map, node=None):
192 202
         return
  203
+
  204
+class NothingNode(object):
  205
+    """
  206
+    A node that matches nothing.
  207
+    """
  208
+    def as_sql(self, qn=None):
  209
+        raise EmptyResultSet
  210
+
  211
+    def relabel_aliases(self, change_map, node=None):
  212
+        return
  213
+
10  tests/regressiontests/model_inheritance_regress/models.py
@@ -43,12 +43,17 @@ class ParkingLot(Place):
43 43
     def __unicode__(self):
44 44
         return u"%s the parking lot" % self.name
45 45
 
  46
+class Supplier(models.Model):
  47
+    restaurant = models.ForeignKey(Restaurant)
  48
+
46 49
 class Parent(models.Model):
47 50
     created = models.DateTimeField(default=datetime.datetime.now)
48 51
 
49 52
 class Child(Parent):
50 53
     name = models.CharField(max_length=10)
51 54
 
  55
+
  56
+
52 57
 __test__ = {'API_TESTS':"""
53 58
 # Regression for #7350, #7202
54 59
 # Check that when you create a Parent object with a specific reference to an
@@ -172,4 +177,9 @@ class Child(Parent):
172 177
 >>> r.id == r.place_ptr_id
173 178
 True
174 179
 
  180
+# Regression test for #7488. This looks a little crazy, but it's the equivalent
  181
+# of what the admin interface has to do for the edit-inline case.
  182
+>>> Supplier.objects.filter(restaurant=Restaurant(name='xx', address='yy'))
  183
+[]
  184
+
175 185
 """}

0 notes on commit a7b556c

Please sign in to comment.
Something went wrong with that request. Please try again.