Ticket #20136: 20136.2.diff

File 20136.2.diff, 2.8 KB (added by Tim Graham, 5 years ago)
  • django/core/serializers/base.py

    diff --git a/django/core/serializers/base.py b/django/core/serializers/base.py
    index 294934a..1e78026 100644
    a b class DeserializedObject(object): 
    161161    def save(self, save_m2m=True, using=None):
    162162        # Call save on the Model baseclass directly. This bypasses any
    163163        # model-defined save. The save is also forced to be raw.
    164         # This ensures that the data that is deserialized is literally
    165         # what came from the file, not post-processed by pre_save/save
    166         # methods.
     164        # raw=True is passed to any pre/post_save signals.
    167165        models.Model.save_base(self.object, using=using, raw=True)
    168166        if self.m2m_data and save_m2m:
    169167            for accessor_name, object_list in self.m2m_data.items():
  • docs/ref/django-admin.txt

    diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
    index 9c193c8..c7fe6eb 100644
    a b application, ``<dirname>/foo/bar/mydata.json`` for each directory in 
    370370:setting:`FIXTURE_DIRS`, and the literal path ``foo/bar/mydata.json``.
    372372When fixture files are processed, the data is saved to the database as is.
    373 Model defined ``save`` methods and ``pre_save`` signals are not called.
     373Model defined :meth:`~django.db.models.Model.save` methods are not called, and
     374any :data:`~django.db.models.signals.pre_save` or
     375:data:`~django.db.models.signals.post_save` signals will be called with
     376``raw=True`` since the instance only contains attributes that are local to the
     377model. You may, for example, want to disable handlers that access
     378related fields that aren't present during fixture loading and would otherwise
     379raise an exception::
     381    from django.db.models.signals import post_save
     382    from .models import MyModel
     384    def my_handler(**kwargs):
     385        # disable the handler during fixture loading
     386        if kwargs['raw']:
     387            return
     388        ...
     390    post_save.connect(my_handler, sender=MyModel)
     392You could also write a simple decorator to encapsulate this logic::
     394    from functools import wraps
     396    def disable_for_loaddata(signal_handler):
     397        """
     398        Decorator that turns off signal handlers when loading fixture data.
     399        """
     400        @wraps(signal_handler)
     401        def wrapper(*args, **kwargs):
     402            if kwargs['raw']:
     403                return
     404            signal_handler(*args, **kwargs)
     405        return wrapper
     407    @disable_for_loaddata
     408    def my_handler(**kwargs):
     409        ...
     411Just be aware that this logic will disable the signals whenever fixtures are
     412deserialized, not just during ``loaddata``.
    375414Note that the order in which fixture files are processed is undefined. However,
    376415all fixture data is installed as a single transaction, so data in
Back to Top