How can I trigger a function when a user registers in django? - django

I took over a django web app and am still relatively new to django. I want to trigger a function whenever a new user registers on the website. But there is no code in the project to process the user registration. It all seems to happen under the hood. So I don't know where could put such a function call. The web app uses django.contrib.auth.
Additionally: How can I trigger a function when an account is activated?

You can use the signals to trigger an event when you save anything in your db, include the User from auth. You can see the django doc about this.
In your case, I think that the best way is like:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import user
#receiver(post_save, sender=User)
def user_saved(sender, instance, **kwargs):
...
In the kwargs you can see, for example, if object is created or modified. The sender is the Class and the instance is the object.

Related

RelatedObjectDoesNotExist at /login/ while running the server locally

I using One To One field in Django to save some extra information about user but even afte migrating i got the issue which i mentioned in title
my models.py
the issue I got
issue while running server
please help if you can
The error you are getting:
User has no profile
Simply means what it says, meaning the particular User instance you are dealing with has no related Profile. Now you might be wondering why not, but that is because a User record can perfectly exist without a 'Profile' relation, the constraint only applies to your profiles, which cannot be created without a corresponding user record.
So if you have somehow tried linking the user to a certain profile, that means the code that is supposed to make that happen isn't doing so and from what I got from the images, you're using signals for that. But I wouldn't recommend doing so, not because signals are generally bad, but because in this case its sorta overkill, and it spreads your code too much.
What I'd suggest/recommend is to add the logic to create profile in the User creation form.
Your problem is probably because the user does not have an associated profile in the DB.
Even though there is an OneToOne relation there doesn't a guarantee. that a user will have a profile.
So you probably need to create a profile for that user.
Also if you want to extend the user model, Ill recommend that you check out this. It contains more ways to achieve what you are looking for
profile doesnt get created automatically ,you need either to add it manually or use signals so that every time a user is created a profile also is created,
if you have a profile model lets say you named it Profile
create a signals.py and add this to it:
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from .models import Profile
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, *args, **kwargs):
if created:
Profile.objects.create(user=instance)
If you're adding blank=True, then why are you adding default=''
If you want profile picture to be mandatory, remove blank=True

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 switch database dynamically

I'd like to switch databases upon user login. I've created this login signal.. but it doesn't work
from django.dispatch import receiver
from django.contrib.auth.signals import user_logged_in
from django.db import connections
#receiver(user_logged_in)
def db_switch(sender, **kwargs):
user_db = 'userdb_%s' % kwargs['user'].username
cursor = connections[user_db].cursor()
The databases are defined in settings.py. Do I have to make this cursor global? Or is this all the way wrong way of doing it?
Thanks!
It's the wrong way of doing it.
Honestly I don't think there is a straightforward, stable way of doing this in Django. It's just not designed for it.
Instead, I'd set up a settings_username.py file for each user, which specifies a secondary database called personal or something. Then, after logging, have them redirect to a new domain, like username.example.com, which uses a unique .wsgi file that pulls in the settingsusername.py file.
Now, as far as the system is concerned, each website is totally separate and unique to that user. Just make sure to set the session cookie to example.com so that they're still logged in when they go to their user website.

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