65
It’s a bit of a hack, but you can do something like this:
use a unique identifier with a filter and then use the update method of the queryset (which does not trigger the signals)
user_id = 142187
User.objects.filter(id=user_id).update(name='tom')
11
ModelName.objects.bulk_create([your object/objects])
also you can read more here django docs
- [Django]-Create Custom Error Messages with Model Forms
- [Django]-Equivalent of PHP "echo something; exit();" with Python/Django?
- [Django]-Django fix Admin plural
7
This ticket has been marked as “wontfix” because:
In short, it sounds like, given the defined purpose of signals, it is
the attached signal handler that needs to become more intelligent
(like in davedash’s suggestion), rather than the code that emits the
signal. Disabling signals is just a quick fix that will work when you
know exactly what handlers are attached to a signal, and it hides the
underlying problem by putting the fix in the wrong place.
- [Django]-Class Based Views VS Function Based Views
- [Django]-Custom validation in Django admin
- [Django]-How to make a POST simple JSON using Django REST Framework? CSRF token missing or incorrect
2
There is currently a ticket pending a Django design decision for this feature.
Included in the ticket is a diff for a patch with the proposed implementation.
- [Django]-Django – makemigrations – No changes detected
- [Django]-Writing test cases for django models
- [Django]-Django: How to create a model dynamically just for testing
1
If you have mutual relations on models and their signals
still you can decouple signal’s logic to have more signals of same type, and handle your logic in more sophisticated way:
You can check in signals, the state of object:
kwargs['created']
You can check the state of any pasted extra value:
So in one signal, you will read at first:
if `kwargs['instance'].skip_signals`:
return
and in another place, before save()
you will just set that skip_signals
on the specific object, in specific situation.
(there is no need to define it as model field)
You can also do not emit signals:
- by overriding method(s) on models,
- or by adding own
save_without_signals()
, - or just as mentioned already, doing
filter(pk=<>).update(...)
- [Django]-Django : Is it impossible to static tag into block tag?
- [Django]-Django: How to pre-populate FormView with dynamic (non-model) data?
- [Django]-How to disable Django's CSRF validation?
1
As far as I’m aware there still isn’t a ‘nice’ way to do this, but if you’re open to exploring hacky solutions, then I’ll add one to the mix.
If you look at the django model source code, specifically save_base()
here and here, you’ll see that the pre_save()
and post_save()
signals are both wrapped in a conditional:
if not meta.auto_created:
// Emit signal
We can directly manipulate the meta options of a model or instance through the _meta
API which means we’re able to ‘disable’ the signals from firing by setting auto_created = True
on the instance we want to save.
For example:
@receiver(post_save, sender=(MyModel))
def save_my_model(sender, instance=None, created=False, **kwargs):
if created:
# Modify the instance
instance.task_id = task.task_hash
# HACK: Prevent `post_save` signal from being called during save
instance._meta.auto_created = True
instance.save()
instance._meta.auto_created = False
elif instance.has_changed("schedule"):
# Modify the instance
instance.task_id = 'abc123'
# HACK: Prevent `post_save` signal from being called during save
instance._meta.auto_created = True
instance.save()
instance._meta.auto_created = False
The major caveat here is that this is undocumented behaviour and it could well change it future releases of django.
- [Django]-How to set a Django model field's default value to a function call / callable (e.g., a date relative to the time of model object creation)
- [Django]-Celery discover tasks in files with other filenames
- [Django]-Automatically create an admin user when running Django's ./manage.py syncdb