blog/content/2013/11/2013-11-13_how-to-not-trigger-a-post_save-in-django-but-still-modify-data.rst
2022-10-16 23:34:35 -04:00

37 lines
2.3 KiB
ReStructuredText
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

How to not trigger a post_save in Django, but still modify data.
################################################################
:date: 2013-11-13 03:58
:author: tyrel
:category: Tech
:tags: django, python
:slug: 2013-11-13-how-to-not-trigger-a-post_save-in-django-but-still-modify-data
: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.