Django

Code

Changeset 7437

Show
Ignore:
Timestamp:
04/20/08 03:47:21 (3 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Added faster paths for updates and inserts that are done
from other core code. This saves a round-trip from field object to field name
and back to field object when we already have the right information to hand.

Files:

Legend:

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

    r7431 r7437  
    309309                # It does already exist, so do an UPDATE. 
    310310                if non_pks: 
    311                     values = [(f.name, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] 
    312                     manager.filter(pk=pk_val).update(**dict(values)
     311                    values = [(f, None, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, False))) for f in non_pks] 
     312                    manager.filter(pk=pk_val)._update(values
    313313            else: 
    314314                record_exists = False 
    315315        if not pk_set or not record_exists: 
    316316            if not pk_set: 
    317                 values = [(f.name, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField)] 
    318             else: 
    319                 values = [(f.name, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields] 
     317                values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField)] 
     318            else: 
     319                values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields] 
    320320 
    321321            if meta.order_with_respect_to: 
    322322                field = meta.order_with_respect_to 
    323                 values.append(('_order', manager.filter(**{field.name: getattr(self, field.attname)}).count())) 
     323                values.append((meta.get_field_by_name('_order')[0], manager.filter(**{field.name: getattr(self, field.attname)}).count())) 
    324324            record_exists = False 
    325325 
     
    327327            if values: 
    328328                # Create a new record. 
    329                 result = manager._insert(__return_id=update_pk, **dict(values)
     329                result = manager._insert(values, return_id=update_pk
    330330            else: 
    331331                # Create a new record with defaults for everything. 
    332                 result = manager._insert(__return_id=update_pk, 
    333                         __raw_values=True, pk=connection.ops.pk_default_value()) 
     332                result = manager._insert([(meta.pk, connection.ops.pk_default_value())], return_id=update_pk, raw_values=True) 
    334333 
    335334            if update_pk: 
  • django/branches/queryset-refactor/django/db/models/manager.py

    r7339 r7437  
    124124        return self.get_query_set().reverse(*args, **kwargs) 
    125125 
    126     def _insert(self, **kwargs): 
    127         return insert_query(self.model, **kwargs) 
     126    def _insert(self, values, **kwargs): 
     127        return insert_query(self.model, values, **kwargs) 
     128 
     129    def _update(self, values, **kwargs): 
     130        return self.get_query_set()._update(values, **kwargs) 
    128131 
    129132class ManagerDescriptor(object): 
  • django/branches/queryset-refactor/django/db/models/query.py

    r7426 r7437  
    288288    update.alters_data = True 
    289289 
     290    def _update(self, values): 
     291        """ 
     292        A version of update that accepts field objects instead of field names. 
     293        Used primarily for model saving and not intended for use by general 
     294        code (it requires too much poking around at model internals to be 
     295        useful at that level). 
     296        """ 
     297        query = self.query.clone(sql.UpdateQuery) 
     298        query.add_update_fields(values) 
     299        query.execute_sql(None) 
     300        self._result_cache = None 
     301    _update.alters_data = True 
     302 
    290303    ################################################## 
    291304    # PUBLIC METHODS THAT RETURN A QUERYSET SUBCLASS # 
     
    693706    transaction.commit_unless_managed() 
    694707 
    695 def insert_query(__model, __return_id=False, __raw_values=False, **kwargs): 
     708def insert_query(model, values, return_id=False, raw_values=False): 
    696709    """ 
    697710    Inserts a new record for the given model. This provides an interface to 
     
    699712    part of the public API. 
    700713    """ 
    701     query = sql.InsertQuery(__model, connection) 
    702     query.insert_values(kwargs, __raw_values) 
    703     return query.execute_sql(__return_id) 
    704  
     714    query = sql.InsertQuery(model, connection) 
     715    query.insert_values(values, raw_values) 
     716    return query.execute_sql(return_id) 
     717 
  • django/branches/queryset-refactor/django/db/models/sql/subqueries.py

    r7428 r7437  
    195195 
    196196    def add_update_values(self, values): 
    197         from django.db.models.base import Model 
     197        """ 
     198        Convert a dictionary of field name to value mappings into an update 
     199        query. This is the entry point for the public update() method on 
     200        querysets. 
     201        """ 
     202        values_seq = [] 
    198203        for name, val in values.iteritems(): 
    199204            field, model, direct, m2m = self.model._meta.get_field_by_name(name) 
    200205            if not direct or m2m: 
    201206                raise FieldError('Cannot update model field %r (only non-relations and foreign keys permitted).' % field) 
     207            values_seq.append((field, model, val)) 
     208        return self.add_update_fields(values_seq) 
     209 
     210    def add_update_fields(self, values_seq): 
     211        """ 
     212        Turn a sequence of (field, model, value) triples into an update query. 
     213        Used by add_update_values() as well as the "fast" update path when 
     214        saving models. 
     215        """ 
     216        from django.db.models.base import Model 
     217        for field, model, val in values_seq: 
    202218            # FIXME: Some sort of db_prep_* is probably more appropriate here. 
    203219            if field.rel and isinstance(val, Model): 
     
    280296        into the query, for example. 
    281297        """ 
    282         func = lambda x: self.model._meta.get_field_by_name(x)[0] 
    283298        # keys() and values() return items in the same order, providing the 
    284299        # dictionary hasn't changed between calls. So the dual iteration here 
    285300        # works as intended. 
    286301        placeholders, values = [], [] 
    287         for name, val in insert_values.iteritems(): 
    288             if name == 'pk': 
    289                 name = self.model._meta.pk.name 
    290             # Getting the Field associated w/the name. 
    291             field = func(name) 
    292  
     302        for field, val in insert_values: 
    293303            if hasattr(field, 'get_placeholder'): 
    294304                # Some fields (e.g. geo fields) need special munging before