Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
@malcolmt malcolmt authored
View
39 django/db/models/sql/where.py
@@ -35,20 +35,30 @@ def add(self, data, connector):
storing any reference to field objects). Otherwise, the 'data' is
stored unchanged and can be anything with an 'as_sql()' method.
"""
+ # Because of circular imports, we need to import this here.
+ from django.db.models.base import ObjectDoesNotExist
+
if not isinstance(data, (list, tuple)):
super(WhereNode, self).add(data, connector)
return
alias, col, field, lookup_type, value = data
- if field:
- params = field.get_db_prep_lookup(lookup_type, value)
- db_type = field.db_type()
- else:
- # This is possible when we add a comparison to NULL sometimes (we
- # don't really need to waste time looking up the associated field
- # object).
- params = Field().get_db_prep_lookup(lookup_type, value)
- db_type = None
+ try:
+ if field:
+ params = field.get_db_prep_lookup(lookup_type, value)
+ db_type = field.db_type()
+ else:
+ # This is possible when we add a comparison to NULL sometimes
+ # (we don't really need to waste time looking up the associated
+ # field object).
+ params = Field().get_db_prep_lookup(lookup_type, value)
+ db_type = None
+ except ObjectDoesNotExist:
+ # This can happen when trying to insert a reference to a null pk.
+ # We break out of the normal path and indicate there's nothing to
+ # match.
+ super(WhereNode, self).add(NothingNode(), connector)
+ return
if isinstance(value, datetime.datetime):
annotation = datetime.datetime
else:
@@ -190,3 +200,14 @@ def as_sql(self, qn=None):
def relabel_aliases(self, change_map, node=None):
return
+
+class NothingNode(object):
+ """
+ A node that matches nothing.
+ """
+ def as_sql(self, qn=None):
+ raise EmptyResultSet
+
+ def relabel_aliases(self, change_map, node=None):
+ return
+
View
10 tests/regressiontests/model_inheritance_regress/models.py
@@ -43,12 +43,17 @@ class ParkingLot(Place):
def __unicode__(self):
return u"%s the parking lot" % self.name
+class Supplier(models.Model):
+ restaurant = models.ForeignKey(Restaurant)
+
class Parent(models.Model):
created = models.DateTimeField(default=datetime.datetime.now)
class Child(Parent):
name = models.CharField(max_length=10)
+
+
__test__ = {'API_TESTS':"""
# Regression for #7350, #7202
# Check that when you create a Parent object with a specific reference to an
@@ -172,4 +177,9 @@ class Child(Parent):
>>> r.id == r.place_ptr_id
True
+# Regression test for #7488. This looks a little crazy, but it's the equivalent
+# of what the admin interface has to do for the edit-inline case.
+>>> Supplier.objects.filter(restaurant=Restaurant(name='xx', address='yy'))
+[]
+
"""}
Please sign in to comment.
Something went wrong with that request. Please try again.