Django

Code

Changeset 7221

Show
Ignore:
Timestamp:
03/11/08 00:36:10 (6 months ago)
Author:
mtredinnick
Message:

queryset-refactor: Reorganised Model.save() to differentiate between public and private parameters. Refs #6741.

This means subclasses can override save() without needing to worry about
passing around the internal parameters (an issue for subclassable models, which
would have meant every model, since you don't know when somebody will subclass
your model).

Slightly backwards incompatible, since it moves "raw" back to being part of the
internal API (it's only needed by the serializer and was intended to be
internal use only). If external code really needs this, they can call
Model.save_base() and pass in raw there.

Files:

Legend:

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

    r6954 r7221  
    163163 
    164164    def save(self, save_m2m=True): 
    165         # Call save on the Model baseclass directly. This bypasses any  
     165        # Call save on the Model baseclass directly. This bypasses any 
    166166        # model-defined save. The save is also forced to be raw. 
    167         # This ensures that the data that is deserialized is literally  
     167        # This ensures that the data that is deserialized is literally 
    168168        # what came from the file, not post-processed by pre_save/save 
    169169        # methods. 
    170         models.Model.save(self.object, raw=True) 
     170        models.Model.save_base(self.object, raw=True) 
    171171        if self.m2m_data and save_m2m: 
    172172            for accessor_name, object_list in self.m2m_data.items(): 
  • django/branches/queryset-refactor/django/db/models/base.py

    r7218 r7221  
    254254        dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self) 
    255255 
    256     def save(self, raw=False, cls=None): 
     256    def save(self): 
     257        """ 
     258        Save the current instance. Override this in a subclass if you want to 
     259        control the saving process. 
     260        """ 
     261        self.save_base() 
     262 
     263    save.alters_data = True 
     264 
     265    def save_base(self, raw=False, cls=None): 
     266        """ 
     267        Does the heavy-lifting involved in saving. Subclasses shouldn't need to 
     268        override this method. It's separate from save() in order to hide the 
     269        need for overrides of save() to pass around internal-only parameters 
     270        ('raw' and 'cls'). 
     271        """ 
    257272        if not cls: 
    258             dispatcher.send(signal=signals.pre_save, sender=self.__class__, 
    259                     instance=self, raw=raw) 
    260273            cls = self.__class__ 
    261274            meta = self._meta 
    262275            signal = True 
     276            dispatcher.send(signal=signals.pre_save, sender=self.__class__, 
     277                    instance=self, raw=raw) 
    263278        else: 
    264279            meta = cls._meta 
     
    266281 
    267282        for parent, field in meta.parents.items(): 
    268             self.save(raw, parent) 
     283            self.save_base(raw, parent) 
    269284            setattr(self, field.attname, self._get_pk_val(parent._meta)) 
    270285 
     
    312327 
    313328        if signal: 
    314             # Run any post-save hooks. 
    315329            dispatcher.send(signal=signals.post_save, sender=self.__class__, 
    316330                    instance=self, created=(not record_exists), raw=raw) 
    317  
    318     save.alters_data = True 
    319331 
    320332    def validate(self): 
  • django/branches/queryset-refactor/docs/db-api.txt

    r7220 r7221  
    160160       is used to provide notification that an object has been successfully 
    161161       saved. (These signals are not yet documented.) 
    162  
    163 Raw saves 
    164 ~~~~~~~~~ 
    165  
    166 **New in Django development version** 
    167  
    168 The pre-processing step (#2 in the previous section) is useful, but it modifies 
    169 the data stored in a field. This can cause problems if you're relying upon the 
    170 data you provide being used as-is. 
    171  
    172 For example, if you're setting up conditions for a test, you'll want the test 
    173 conditions to be repeatable. If pre-processing is performed, the data used 
    174 to specify test conditions may be modified, changing the conditions for the 
    175 test each time the test is run. 
    176  
    177 In cases such as this, you need to prevent pre-processing from being performed 
    178 when you save an object. To do this, you can invoke a **raw save**  by passing 
    179 ``raw=True`` as an argument to the ``save()`` method:: 
    180  
    181     b4.save(raw=True) # Save object, but do no pre-processing 
    182  
    183 A raw save skips the usual data pre-processing that is performed during the 
    184 save. All other steps in the save (pre-save signal, data preparation, data 
    185 insertion, and post-save signal) are performed as normal. 
    186  
    187 .. admonition:: When to use a raw save 
    188  
    189     Generally speaking, you shouldn't need to use a raw save. Disabling field 
    190     pre-processing is an extraordinary measure that should only be required 
    191     in extraordinary circumstances, such as setting up reliable test 
    192     conditions. 
    193162 
    194163Saving changes to objects 
  • django/branches/queryset-refactor/tests/modeltests/signals/models.py

    r7086 r7221  
    6767Is updated 
    6868 
    69 >>> p1.save(raw=True) 
     69# Calling an internal method purely so that we can trigger a "raw" save. 
     70>>> p1.save_base(raw=True) 
    7071pre_save_nokwargs signal 
    7172pre_save signal, Tom Smith 
  • django/branches/queryset-refactor/tests/regressiontests/serializers_regress/tests.py

    r5898 r7221  
    3232    instance = klass(id=pk) 
    3333    instance.data = data 
    34     models.Model.save(instance, raw=True) 
     34    models.Model.save_base(instance, raw=True) 
    3535    return instance 
    3636 
     
    3838    instance = klass(id=pk) 
    3939    instance.data = data[0] 
    40     models.Model.save(instance, raw=True) 
     40    models.Model.save_base(instance, raw=True) 
    4141    for tag in data[1:]: 
    4242        instance.tags.create(data=tag) 
     
    4646    instance = klass(id=pk) 
    4747    setattr(instance, 'data_id', data) 
    48     models.Model.save(instance, raw=True) 
     48    models.Model.save_base(instance, raw=True) 
    4949    return instance 
    5050 
    5151def m2m_create(pk, klass, data): 
    5252    instance = klass(id=pk) 
    53     models.Model.save(instance, raw=True) 
     53    models.Model.save_base(instance, raw=True) 
    5454    instance.data = data 
    5555    return instance 
     
    5858    instance = klass() 
    5959    instance.data_id = data 
    60     models.Model.save(instance, raw=True) 
     60    models.Model.save_base(instance, raw=True) 
    6161    return instance 
    6262 
     
    6464    instance = klass() 
    6565    instance.data = data 
    66     models.Model.save(instance, raw=True) 
     66    models.Model.save_base(instance, raw=True) 
    6767    return instance 
    6868 
     
    310310 
    311311    obj = ComplexModel(field1='first',field2='second',field3='third') 
    312     obj.save(raw=True
     312    obj.save(
    313313 
    314314    # Serialize then deserialize the test database 
     
    326326 
    327327    obj = ComplexModel(field1='first',field2='second',field3='third') 
    328     obj.save(raw=True
     328    obj.save(
    329329 
    330330    # Serialize the test database to a stream