Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
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.