blog/content/2013/11/2013-11-13_how-to-not-trigger-a-post_save-in-django-but-still-modify-data.rst

37 lines
2.3 KiB
ReStructuredText
Raw Normal View History

2022-10-17 01:59:22 +00:00
How to not trigger a post_save in Django, but still modify data.
################################################################
:date: 2013-11-13 03:58
:author: tyrel
2022-10-17 03:02:04 +00:00
:category: Tech
:tags: django, python
2022-10-17 03:34:35 +00:00
:slug: 2013-11-13-how-to-not-trigger-a-post_save-in-django-but-still-modify-data
2022-10-17 01:59:22 +00:00
:status: published
Recently I have been diving into using signals with Django, which of course are pretty neat.
I am working on a website for work which in the most basic explanation, is a task management site. Recently I have added in the ability to subscribe to tasks and get emails, I did this by connecting to the post_save signal. I only email out when a task is changed, not created (of course, no one would be subscribed to it). This worked flawlessly and “emails” out to anyone who is subscribed. I say that in quotes, because I havent actually hooked it up to a real SMTP server, and only use
.. code:: console
python -m smtpd -n -c DebuggingServer localhost:1025
which will output any emails to stdout.  But I digress… A problem arose when I was working on ordering tasks.
I store an integer in the “ordering” column, which any authenticated user can drag the row to a new location and that will reorder the task. I did this after I setup the emailing signal, so I didnt think about an email being sent out for EVERY task being changed.
I tried a lot of different things, and was debating some that would be a bit messy. Among those ideas were trying to store the past values in another table, but that would get expensive fast. The reason I tried this was because I wanted to see if the ordering was the only thing that changed, and if that was the case, not send an email. I eventually found a thread on StackOverflow that says to use update on the queryset to not trigger the signal.
You can do this by doing something like this:
.. code:: python
from app.models import ModelName
def reorder(request):
new_order = request.POST.get('new_order',None)
pk = request.POST.get('modelname_pk',None)
if new_order:
ModelName.objects.filter(pk=pk).update(ordering=new_order)
I am not sure if this is the proper way save changes and not trigger a post_save signal, but this is the way that worked for me so I figured I would document this.