Why use signals in Django? - django

I have read lots of documentation and articles about using signals in Django, but I cannot understand the concept.
What is the purpose of using signals in Django?
How does it work?
Please explain the concept of signals and how to use it in Django code.

The Django Signals is a strategy to allow decoupled applications to get notified when certain events occur. Let’s say you want to invalidate a cached page everytime a given model instance is updated, but there are several places in your code base that this model can be updated. You can do that using signals, hooking some pieces of code to be executed everytime this specific model’s save method is trigged.
Another common use case is when you have extended the Custom Django User by using the Profile strategy through a one-to-one relationship. What we usually do is use a “signal dispatcher” to listen for the User’s post_save event to also update the Profile instance as well.

Related

Django: Last modified by and created by user automatic saving

The age-old question: How can I automatically save last_modifed_user in django models?
I found in several places this general process how to do it using thread local. I'm hesitant to simply implement it that way because I'm not entirely sure of the consequences it has and because all these posts are old.
Is using thread local still the "recommended" way of doing this in django 3? Or does django3 have a better options of doing it?
No, this hasn't changed. Simply because separation of concern is an architectural principle of MVC (model-view-controller), which is also how Django (model-view-template) and most web frameworks with ORM are architected. Models know nothing about the request, it's not available (and in many cases there isn't a request at all when a model is saved, think of management commands or regular tasks running in the background).
The alternative to thread local is to make sure you implement it yourself in the controller layer (view layer in Django):
Create a view mixin that you can mix with all the generic views that use the ModelFormMixin to save the user into the model (ModelFormMixin.form_valid()). Or combine it with a form mixin where the user is passed to the form (FormMixin.get_form_kwargs()) and saved when the form is saved (ModelForm.save()).
Create a ModelAdmin mixin that does the same when saving a model in the django admin site.
This of course means someone on your team may forget to do it when creating new views and forms. The link you posted contains an answer as to the advantages and disadvantages of using thread local.

Where is the best place to send email in django-rest-framework?

I want to send emails in django rest framework, for example when someone creates an account,or comments something and etc. I found this in django documents. But I don't know where to use it. maybe in Viewset but in which method.
so what is the best way and where is the best place to send emails in Django Rest Framework?
I would like to give you couple of suggestions(Of course, with reasons):
That is synchronous. Maybe that would be not desired/efficient. I would suggest you to use something like this package (django-anymail) , this will decouple your email sender. Assume now you're using AWS SES, tomorrow you want to switch to sendgrid, then you'll only need to change setting variables with this.
Assuming User, Comment each of these are separate models. I would suggest you to override the save() method of these models and send email from there. I am not suggesting signals because I feel (fully personal view) that signals are to be used when access to the source is not possible, like some event in 3rd party library, etc.
Assuming that "Creating an account" and "commenting on something" both create some model instance, you could use existing model signals.
If you need to catch events that don't already send a signal, you will have to define new signals and send them from the appropriate place (which depends on what you're interested in so no 'one-size-fits-all' answer here).
Also if you have more than one mail to send at a time you may want to consider using some async task queue to send the emails - this avoids delaying the response (django signals are NOT async).
You can register sending function to some django signals or You can call it in Class-based Views or Function Based Views.

Add a function in models.py or managers.py

I'd like to send an activation link to a new registered user. Should I write my function in my models.py or managers.py?
It's always confused to me to know where put the function, even after reading the documentation.
None of them, models and managers are related to application data. Sending emails are related to the logic of your app: actions, decisions, answers ... so you should do this in a view.
If you need to save time, you can use Django Registration as #karthikr suggests to you, this app is a good wrapper for reaching this aim.
I've assumed you need to send the link in the moment that the user has registered, but if you want to do this in other moment you can use a scheduled task: a django cron, an external python process or ...; that is up to you: your porpuse, the design of your app.
This blog could help you understand the use of managers better.
I would put the activation link in managers, because it would be easier to manage the various activities around it - resend activation link, validation, etc. It could be done with models too, but managers make it more modular.
Django Registration is quitely widely used for registration - you could see how it is implemented there as well.
Yes , you can write your customized function in models.py but not sure about manage.py .
I have used signal method in models.py to for mailservice facility.

post_save in the admin

I have a application that i exclusively use with the admin.
I would like to send an email every time that a new object is created/modified, from my search, it seems that using the post_save would be the best way.
Unfortunately the doc is not really clear on that...
Can someone explain me > maybe with an example ?
Thanks
There are two ways. Either override the save function or use signals.
See the following excellent posts:
Django Signals
Django Signals vs Save (linked to archive.org original removed)
For a simple similar example using save have a look at my previous answer:
Send an e-mail notification when a Django CharField is modified via the admin site

How to implement non-database backed models in Django?

I have an existing Django application with a pretty typical model implementation that's backed by a database. My task is to change this model so that instead of fetching the information from a database, it now fetches it from a service (e.g., via HTTP). Because there is existing code which already makes use of this model, it would be nice to maintain the same model interface so that it continues to behave like a typical Django model.
This raises a few of questions:
Is it possible to do this without having to re-write the interface from scratch to make it look like Django's model interface? (This stackoverflow question would seem to suggest otherwise: Django MVC pattern for non database driven models?)
Would writing a custom manager for this model be an appropriate approach (or have I misunderstood the role of the manager)?
Due to the service-backed nature of the new model, caching will be much more important than before. Is this something that should be implemented at the model level?
Have a look at django-roa. From the sound of it, it might be exactly what you are looking for.