Commit a7b556ca authored by Malcolm Tredinnick's avatar Malcolm Tredinnick
Browse files

Allow for matches against unsaved objects in querysets (which will therefore

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
parent 39124035
Loading
Loading
Loading
Loading
+30 −9
Original line number Diff line number Diff line
@@ -35,20 +35,30 @@ class WhereNode(tree.Node):
        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
        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).
                # 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 @@ class EverythingNode(object):

    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
+10 −0
Original line number Diff line number Diff line
@@ -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 @@ True
>>> 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'))
[]

"""}