Django Signal not adding user to a group - django

I am trying to add a user to a group when the user is created. I have seen a few different ways to accomplish similar things with signals but nothing I am trying has seemed to work.
In the shell, I ran Group.objects.get(name='User') to make sure that the group was being recognized.
signals.py
from django.db.models.signals import post_save
from django.contrib.auth.models import User, Group
from django.dispatch import receiver
#receiver(post_save, sender=User)
def add_user_to_user_group(sender, instance, created, **kwargs):
try:
if created:
instance.groups.add(Group.objects.get(name='User'))
except Group.DoesNotExist:
pass
This part I am very unsure of, I have seen a few different ways people have done this part. One tutorial did it this way but I am not sure what just importing the signals would do
app.py
from django.apps import AppConfig
class UserConfig(AppConfig):
name = 'User'
def ready(self):
import User.signals

Related

Effecient way to add default user to model object which is created by other users

My User has 2 objects.
1. admin - super admin
2. tom - user
MyModel with
class MyModel:
project_user = models.ManyToManyField(User)
Let's suppose tom is creating a MyModel object:
MyModel(project_user=request.user).save()
Here I would like to add admin user automatically to the project_user object when someone creates an object. What will the more efficient way to implement it,How about using signals or def save(self)?
I would recommend using Signals.
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
In the snippet above, I'm trying to create a custom model (i.e. Profile) when a default user once created.
Therefore, I think you could write like this:
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=MyModel)
def create_user(sender, instance, created, **kwargs):
if created:
User.objects.create_user(username=instance.username)
And create_user() is a helper function of Django.
Edit: Added what I import in the snippet.

I m confused about the ready function used inside app.py

i m doing some project using django frame work i am a beginner and just used
django signals but i m confused that why do we need to imporrt signals file in app.py inside the ready function
code below makes question more clear i m stuck in this so require help
signal.py
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,**kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save,sender=User)
def save_profile(sender,instance,**kwargs):
instance.profile.save()
app.py
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
#i have no idea what this function does
what is the need of ready function here and why is it importing signals here???
what if i import signals at the top without using ready function??
what is the need of ready function here and why is it importing signals here?
The ready() method [Django-doc] is called after the registry is fully loaded. You thus can then perform some operations you want to perform before the server starts handling requests. This is specified in the documentation:
Subclasses can override this method to perform initialization tasks such as registering signals. It is called as soon as the registry is fully populated.
The reason the signals are imported here is because Django will not import the signals if you do not import those explicitly. If the signals module is not imported, then the signals are not registered on the corresponding models, and hence if you for example make changes to your User model, the signals will not be triggered.
Usually one adds a #noqa comment to the import line, to prevent a linter tool like pylint to raise warnings about an import that you do not use.
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals # noqa

Signals not works? I want create profile instance when user was created

I read a part of the doc, and some articles, but my code is not working.
OBS: i'm using custom User created with AbstractUser, but i not add extra fields
Look this example
profile.signals.py:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from .models import Profile
User = get_user_model()
#receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
now, look in the user creation:
>>> from accounts.models import User
>>> me = User.objects.create(username='myusr', email='me#email.com', password='me123456')
>>> me
<User: myusr>
>>> me.save()
>>> me.profile
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/mnt/sda4/Development/coding/Projects/codesv3/env/lib/python3.7/site-packages/django/db/models/fields/related_descriptors.py", line 415, in__get__
self.related.get_accessor_name()
accounts.models.User.profile.RelatedObjectDoesNotExist: User has no profile.
i dont know what's wrong. Also because I have not used it before and i not know about SQL triggers
In your signals.py file, save profile after it's created, like below:
#receiver(post_save, sender=User)
def save_profile(sender, instance, **kwargs):
instance.profile.save()
Make sure, you import signals in your related apps.py file like below example:
from django.apps import AppConfig
class UsersConfig(AppConfig):
name = 'users'
def ready(self):
import users.signals
Then also make sure you have made the below change:
you must add app's config to either of two files.
In your settings.py file's INSTALLED_APPS, like mentioned in this link: Django create profile for user signal.
OR,
In your related app's __init__.py file, like this (in this example, the related app is users): default_app_config = 'users.apps.UsersConfig'
First, this command create user and you do not need to save it after creating:
me = User.objects.create(username='myusr', email='me#email.com', password='me123456')
Second, where your signals places? If you put it in models everything should works.
Also you can place where you want but you need to import it in your apps like here:
class ProfileConfig(BaseConfig):
name = ...
def ready():
import profiles.signals # where your signals place

Assign default group to new user Django

I'm trying to assign a group to every new user registered into the system. I've already read something about it in another questions but I don't really know where to add the necessary code to make it work.
I'm using Django 2.1.3 and I'm logging users using allauth (social login, but it shouldn't make any difference as a new instance in the User table is created)
You can use a #post_save signal for example that, each time a User is created, adds the given group to the groups of the User. Typically signals reside in a file named handlers.py in the signals directory of an app, so you probably should create or modify the files listed in boldface:
app/
signals/
__init__.py
handlers.py
__init__.py
apps.py
...
# app/signals/handlers.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
from django.contrib.auth.models import Group
#receiver(post_save, sender=settings.AUTH_USER_MODEL)
def save_profile(sender, instance, created, **kwargs):
if created:
g1 = Group.objects.get(name='group_name')
instance.groups.add(g1)
where group_name is the name of the group you want to add.
You should then import the handlers.py module in your MyAppConfig (create one if you do not have constructed such config yet):
# app/apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'app'
verbose_name = "My app"
def ready(self):
import app.signals.handlers
and register the MyAppConfig in the __init__.py of the app:
# app/__init__.py
default_app_config = 'app.apps.MyAppConfig'
If this should happen for any new User instance, you can connect a handler to the post_save signal:
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=User)
def handle_new_job(sender, **kwargs):
if kwargs.get('created', False):
user = kwargs.get('instance')
g = Group.objects.get(name='whatever')
user.groups.add(g)
Include this code in your app and make sure it is imported as stated e.g. here.

Why does the signal not trigger?

Sitting over a day on it. Really can't understand why this signal is not triggered when a user is activated, no error log, no exception in the admin on activation. Can anybody help? The following code should result in a log message in the apache error.log when a user, right?
import logging
from django.dispatch import receiver
from registration.signals import user_activated
#receiver(user_activated)
def registered_callback(sender, **kwargs):
logger = logging.getLogger("user-activated")
logger.error("activated here")
same with user_registered
First of all im using django 1.8.3 .You should register your signal first. As far as i know, there are some methods to do that but this is what im doing;
Create signals.py in your app write your signal there;
from django.db.models.signals import post_save
from django.dispatch import receiver
#receiver(post_save, sender=your_model,dispatch_uid="yourmodel_save_receiver")
def post_save_yourmodel(sender, instance, **kwargs):
if instance.profile_status:
print "active"
else:
print "not active"
Then you should create apps.py. This file contains configuration information to your model.
from django.apps import AppConfig
class yourmodel_config(AppConfig):
name = 'yourmodel_config'
verbose_name = 'your_model config'
def ready(self):
import yourmodel.signals
With this whenever your app is ready, your signals will be imported
Finally open your __init__.py and add the following.
default_app_config = 'yourmodel.apps.yourmodel_config'
With this you are defining application configuration for your model.This example when ever yourmodel is saved, signal checks for profile_status attribute and prints output depending on the value(true or false) to your console. You can also add created parameter to your model to know that if instance of the model is created. created will return True if a new record was created. def post_save_yourmodel(sender, instance, created, **kwargs):. Otherwise this signal will be triggered whenever your model is saved with yourmodel.save().
Consider that is a post_save example.You can find list of the model signals from here.