Django

Code

Changeset 8061

Show
Ignore:
Timestamp:
07/23/08 01:12:15 (6 months ago)
Author:
mtredinnick
Message:

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).

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/db/models/sql/where.py

    r7835 r8061  
    3636        stored unchanged and can be anything with an 'as_sql()' method. 
    3737        """ 
     38        # Because of circular imports, we need to import this here. 
     39        from django.db.models.base import ObjectDoesNotExist 
     40 
    3841        if not isinstance(data, (list, tuple)): 
    3942            super(WhereNode, self).add(data, connector) 
     
    4144 
    4245        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 
    5262        if isinstance(value, datetime.datetime): 
    5363            annotation = datetime.datetime 
     
    191201    def relabel_aliases(self, change_map, node=None): 
    192202        return 
     203 
     204class 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 
  • django/trunk/tests/regressiontests/model_inheritance_regress/models.py

    r8051 r8061  
    4444        return u"%s the parking lot" % self.name 
    4545 
     46class Supplier(models.Model): 
     47    restaurant = models.ForeignKey(Restaurant) 
     48 
    4649class Parent(models.Model): 
    4750    created = models.DateTimeField(default=datetime.datetime.now) 
     
    4952class Child(Parent): 
    5053    name = models.CharField(max_length=10) 
     54 
     55 
    5156 
    5257__test__ = {'API_TESTS':""" 
     
    173178True 
    174179 
     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 
    175185"""}