Django signals pre_delete accessing request.user - django

Is there a way to access request.user within pre_delete signal? I found an answer but that was 10 years ago and doesn't work with the current version of Django.

Related

Using Django admin site in other applications [duplicate]

This question already has answers here:
Django admin search/filter functionality as a page table
(2 answers)
Closed 5 years ago.
My goal is to develop a web-application that would retrieve data from a database and display them in a table.
I'm new to the web-development, this task is not my main goal, therefore, I'd like to spend minimum efforts for it.
I've chosen Django for this task. I've got familiar with its admin site from the official tutorial, and can conclude that it has all required functionality (retrieving, sorting, filtering, search).
In parallel, I've installed django-tables2. It requires much more efforts, for example, writing CSS templates, while admin has all included.
Is it possible to use that admin site like ordinary web app just to display data, without adding or deletion?
Yes, you can do that. I have done it before. The challange is to create your target database structure. Django has an manage.py inspectdb command you can use to generate models from the target database. You would only need to override the ModelAdmin, so you cannot save it.
class CustomAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
pass

How to execute code after authentication in Django?

I want to execute one or more functions after a user logs into my site. How is this possible? I looked into Middleware. Djangobook says that I'll need this to run a piece of code on each and every request that Django handles. However, I just need the code run when the authentication happens successfully.
Note: I am using Django Allauth for authentication and I don't have any view of my own to log in users.
You need to tap into Allauth's signals. Specifically the user logged in signal
allauth.account.signals.user_logged_in(request, user)
Sent when a user logs in.
So add code similar to the following in your project.
from django.dispatch.dispatcher import receiver
from allauth.account.signals import user_logged_in
#receiver(user_logged_in, dispatch_uid="unique")
def user_logged_in_(request, user, **kwargs):
print request.user
This code should be in a place that's likely to be read when django starts up. models.py and views.py are good candidates.
As per the official documentation, there is a signal allauth.account.signals.user_logged_in which gets triggered when a user logs in. This can serve your purpose.

Django TastyPie, how to trigger action after POST with ManyToMany fields?

I have a REST API built using Django and TastyPie. My goal is to add a task to my job queue when new data is POSTed to a particular model.
I was going to hook into post_save and trigger then but the model contains ManyToMany relationships and so the post_save is triggered before the m2m relationships update and hooking into the m2m_changed signal seems messy. I get multiple signal events and my code will need to check the instance after each one and try and determine if it's ready to trigger the event. Some of the ManyToMany fields can be Null so when I get an m2m_changed signal I don't really know for sure if it's done saving.
Is there a correct way to do this? Does TastyPie allow me to hook into the POST event and do something at the end? All the things I have found point me at post_save events to do this.
Does Django have a way to signal me when all m2m updates for a given model instance are completed?
If you are using POST, then obj_update() does not appear to work for me. What did work was using obj_create() as follows:
class Resource(ModelResource):
def obj_create(self,bundle,**kwargs):
bundle = super(Resource,self).obj_create(bundle,**kwargs)
# Add code here
return bundle
One thing to note is that request is not included. I tried that and it gave me an error.
You should be able to override the obj_update method
class Resource(ModelResource):
def obj_update(self, bundle, request, **kwargs):
bundle = super(Resource, self).obj_update(bundle, **kwargs)
# queue your task here
return bundle

Updating when database has changed in Django

I have many records in my database that are displayed on a screen. However, the records are user generated and sometimes have to be removed. Each record has a show field which is initially always set to true. When we get content that has to be removed a human will set it to false in the Django admin interface. When this happens, we need the bad content to be removed from the screen. So my question is, in the Django interface, what is the way to tell when a record has been updated and do something in response to this change?
You should read about signals:
An Idea on how doing this:
from django.core.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=MyModel)
def my_handler(sender, instance, created, raw, **kwargs):
if created: # True for save, False for update
...
I think this could help you tell when the record its being updated and when you can do something about it.
But if the user seeing the records wont have to refresh the page so the record is hidden, then you could use websockets to receive that information your signal sent. Or you can just do ajax requests every 20-30 seconds to check all the records and discovery which one is hidden, or you can check a list of latest hidden records that your signal will populate.
Anyway, there is different ways of doing this.

Is there a way to list Django signals?

Is there a way to see which signals have been set in Django?
It's not really exposed in docs but Signal is just a class that contains a list of receivers which are called on event. You can manually check this list:
from django.db.models.signals import *
for signal in [pre_save, pre_init, pre_delete, post_save, post_delete, post_init, post_syncdb]:
# print a List of connected listeners
print signal.receivers
There's a django app called
django-debug-toolbar which adds a little toolbar at the top of all django served pages providing info related to the backend of the page's rendering, such as how many queries were executed, how much time they each took, etc. It also prints out signals. I don't use signals in my app, so I have never used that feature, but it's there.
I wrote little command that shows all signal listeners: https://gist.github.com/1264102
You can modify it to show signals only.
If you want to list only the connected receivers for a specific signal on a specific model, you can look at _live_receivers. For instance, if you want to list the connected post_save hooks for a model named MyModel, you can do:
from django.db.models.signals import post_save
from models import MyModel
print(post_save._live_receivers(MyModel))
I found this approach in the Django source code by looking for how has_listeners works: https://github.com/django/django/blob/3eb679a86956d9eedf24492f0002de002f7180f5/django/dispatch/dispatcher.py#L153