Django

Code

Changeset 7241

Show
Ignore:
Timestamp:
03/14/08 06:46:26 (8 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Second part of select_related() fix.

Relations on the parent model can now be specified as part of the fields list.
Fixed #6761.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/queryset-refactor/django/db/models/sql/query.py

    r7240 r7241  
    770770        if not opts: 
    771771            opts = self.get_meta() 
    772             root_alias = self.tables[0] 
     772            root_alias = self.get_initial_alias() 
    773773            self.select.extend(self.get_default_columns()) 
    774774        if not used: 
    775             used = [] 
     775            used = set() 
    776776 
    777777        # Setup for the case when only particular related fields should be 
     
    784784                restricted = False 
    785785 
    786         for f in opts.fields
     786        for f, model in opts.get_fields_with_model()
    787787            if (not f.rel or (restricted and f.name not in requested) or 
    788788                    (not restricted and f.null) or f.rel.parent_link): 
    789789                continue 
    790790            table = f.rel.to._meta.db_table 
    791             alias = self.join((root_alias, table, f.column, 
     791            if model: 
     792                int_opts = opts 
     793                alias = root_alias 
     794                for int_model in opts.get_base_chain(model): 
     795                    lhs_col = int_opts.parents[int_model].column 
     796                    int_opts = int_model._meta 
     797                    alias = self.join((alias, int_opts.db_table, lhs_col, 
     798                            int_opts.pk.column), exclusions=used) 
     799            else: 
     800                alias = root_alias 
     801            alias = self.join((alias, table, f.column, 
    792802                    f.rel.get_related_field().column), exclusions=used) 
    793             used.append(alias) 
     803            used.add(alias) 
    794804            self.select.extend([(alias, f2.column) 
    795805                    for f2 in f.rel.to._meta.fields]) 
  • django/branches/queryset-refactor/tests/modeltests/model_inheritance/models.py

    r7230 r7241  
    4343# 
    4444 
     45class Chef(models.Model): 
     46    name = models.CharField(max_length=50) 
     47 
     48    def __unicode__(self): 
     49        return u"%s the chef" % self.name 
     50 
    4551class Place(models.Model): 
    4652    name = models.CharField(max_length=50) 
     
    6066    serves_hot_dogs = models.BooleanField() 
    6167    serves_pizza = models.BooleanField() 
     68    chef = models.ForeignKey(Chef, null=True, blank=True) 
    6269 
    6370    class Meta(Rating.Meta): 
     
    137144 
    138145# Test the constructor for ItalianRestaurant. 
    139 >>> ir = ItalianRestaurant(name='Ristorante Miron', address='1234 W. Ash', serves_hot_dogs=False, serves_pizza=False, serves_gnocchi=True, rating=4) 
     146>>> c = Chef(name="Albert") 
     147>>> c.save() 
     148>>> ir = ItalianRestaurant(name='Ristorante Miron', address='1234 W. Ash', serves_hot_dogs=False, serves_pizza=False, serves_gnocchi=True, rating=4, chef=c) 
    140149>>> ir.save() 
    141150>>> ir.address = '1234 W. Elm' 
     
    145154# order. 
    146155>>> [f.name for f in Restaurant._meta.fields] 
    147 ['id', 'name', 'address', 'place_ptr', 'rating', 'serves_hot_dogs', 'serves_pizza'
     156['id', 'name', 'address', 'place_ptr', 'rating', 'serves_hot_dogs', 'serves_pizza', 'chef'
    148157>>> [f.name for f in ItalianRestaurant._meta.fields] 
    149 ['id', 'name', 'address', 'place_ptr', 'rating', 'serves_hot_dogs', 'serves_pizza', 'restaurant_ptr', 'serves_gnocchi'] 
     158['id', 'name', 'address', 'place_ptr', 'rating', 'serves_hot_dogs', 'serves_pizza', 'chef', 'restaurant_ptr', 'serves_gnocchi'] 
    150159>>> Restaurant._meta.ordering 
    151160['-rating'] 
     
    159168Traceback (most recent call last): 
    160169    ... 
    161 FieldError: Cannot resolve keyword 'supplier' into field. Choices are: address, id, italianrestaurant, lot, name, place_ptr, provider, rating, serves_hot_dogs, serves_pizza 
     170FieldError: Cannot resolve keyword 'supplier' into field. Choices are: address, chef, id, italianrestaurant, lot, name, place_ptr, provider, rating, serves_hot_dogs, serves_pizza 
    162171 
    163172# Parent fields can be used directly in filters on the child model. 
     
    241250True 
    242251 
     252# select_related works with fields from the parent object as if they were a 
     253# normal part of the model. 
     254>>> from django import db 
     255>>> from django.conf import settings 
     256>>> settings.DEBUG = True 
     257>>> db.reset_queries() 
     258>>> ItalianRestaurant.objects.all()[0].chef 
     259<Chef: Albert the chef> 
     260>>> len(db.connection.queries) 
     2612 
     262>>> ItalianRestaurant.objects.select_related('chef')[0].chef 
     263<Chef: Albert the chef> 
     264>>> len(db.connection.queries) 
     2653 
     266 
    243267"""}