Browse files

Fixed #20136 - Fixed and expanded the docs for loaddata and model sig…


Thanks brandon@ and Anssi for the report.
  • Loading branch information...
1 parent 679a2ac commit 2c62a509deb50e39375b0cd44cfc85a743978fdc @timgraham timgraham committed May 11, 2013
Showing with 41 additions and 4 deletions.
  1. +1 −3 django/core/serializers/
  2. +40 −1 docs/ref/django-admin.txt
@@ -161,9 +161,7 @@ def __repr__(self):
def save(self, save_m2m=True, using=None):
# Call save on the Model baseclass directly. This bypasses any
# model-defined save. The save is also forced to be raw.
- # This ensures that the data that is deserialized is literally
- # what came from the file, not post-processed by pre_save/save
- # methods.
+ # raw=True is passed to any pre/post_save signals.
models.Model.save_base(self.object, using=using, raw=True)
if self.m2m_data and save_m2m:
for accessor_name, object_list in self.m2m_data.items():
@@ -373,7 +373,46 @@ application, ``<dirname>/foo/bar/mydata.json`` for each directory in
:setting:`FIXTURE_DIRS`, and the literal path ``foo/bar/mydata.json``.
When fixture files are processed, the data is saved to the database as is.
-Model defined ``save`` methods and ``pre_save`` signals are not called.
+Model defined :meth:`` methods are not called, and
+any :data:`~django.db.models.signals.pre_save` or
+:data:`~django.db.models.signals.post_save` signals will be called with
+``raw=True`` since the instance only contains attributes that are local to the
+model. You may, for example, want to disable handlers that access
+related fields that aren't present during fixture loading and would otherwise
+raise an exception::
+ from django.db.models.signals import post_save
+ from .models import MyModel
+ def my_handler(**kwargs):
+ # disable the handler during fixture loading
+ if kwargs['raw']:
+ return
+ ...
+ post_save.connect(my_handler, sender=MyModel)
+You could also write a simple decorator to encapsulate this logic::
+ from functools import wraps
+ def disable_for_loaddata(signal_handler):
+ """
+ Decorator that turns off signal handlers when loading fixture data.
+ """
+ @wraps(signal_handler)
+ def wrapper(*args, **kwargs):
+ if kwargs['raw']:
+ return
+ signal_handler(*args, **kwargs)
+ return wrapper
+ @disable_for_loaddata
+ def my_handler(**kwargs):
+ ...
+Just be aware that this logic will disable the signals whenever fixtures are
+deserialized, not just during ``loaddata``.
Note that the order in which fixture files are processed is undefined. However,
all fixture data is installed as a single transaction, so data in

0 comments on commit 2c62a50

Please sign in to comment.