I want to know if there are any specific signals sent when the first superuser is created. Am talking about when I run syncdb and am asked to create a super user. At that point I want to know if any signals are sent so that I can Use the signal to do some initialization. Or is there a way I can have a piece of code run only at that moment when the first super user is created. I want that piece of code to run only once at the beginning. help pls. I hope this question makes sense... of late I'v been getting criticism that my questions don't make sense. I hope this one does
def superuser_creation(sender, instance, created, **kwargs):
user = kwargs['instance']
if user.is_superuser:
//do something here
post_save.connect(superuser_creation, sender=User)
The creating of superuser is invoked by post_syncdb signal, you could hook to the post_syncdb signal as well and run the extra code afterwards.
Put the following code to the management/__init__.py of one of your app and make sure the path of that app is under the django.contrib.auth, in settings.INSTALLED_APPS.
from django.contrib.auth import models as auth_app
from django.db.models import signals
def operate_upon_first_superuser_after_syncdb(app, created_models, verbosity, db, **kwargs):
if auth_app.User in created_models and kwargs.get('interactive', True):
if auth_app.User.objects.filter(is_superuser=True).exists():
# ... extra code here
signals.post_syncdb.connect(operate_upon_first_superuser_after_syncdb,
sender=auth_app, dispatch_uid='operate_upon_first_superuser_after_syncdb')
Related
I have a OneToOneField between my UserTrust model and django.contrib.auth.models.User that I would like to create whenever a new User registers. I thought on creating the UserTrust instance using the user_signed_up signal.
I have the following code in my AppConfig
def ready(self):
# importing model classes
from .models import UserTrust
#receiver(user_signed_up)
def create_usertrust(sender, **kwargs):
u = kwargs['user']
UserTrust.objects.create(user=u)
... and this is in my pytest test
#pytest.fixture
def test_password():
return 'strong-test-pass'
#pytest.fixture
def create_user(db, django_user_model, test_password):
def make_user(**kwargs):
kwargs['password'] = test_password
if 'username' not in kwargs:
kwargs['username'] = str(uuid.uuid4())
return django_user_model.objects.create_user(**kwargs)
return make_user
#pytest.mark.django_db
def test_my_user(create_user):
user = create_user()
assert user.usertrust.available == 1000
Still, the test fails with
django.contrib.auth.models.User.usertrust.RelatedObjectDoesNotExist: User has no usertrust.
What did I miss?
The problem with you creating the user via the django_user_model is that it doesn't actually pass through the allauth code that actually sends that signal. You've got two options:
Use a client (since I'm assuming you're using pytest-django) and fill out a registration via the allauth provided link for registering new users. That way, a signal is sent, and you can assert attributes and model instances like that.
You can simply ignore the signal and unittest the function itself. That's it. You put your trust in that single registration view not changing at all and put your trust in the package that the API will not change. I can still recommend this option, but you've been warned.
You can send the signal yourself. Not recommended in case allauth's API changes, but you could just import the signal from allauth and send it like this: user_signed_up.send(sender=self.__class__, toppings=toppings, size=size) where user_signed_up is the signal. Ref the docs: https://docs.djangoproject.com/en/dev/topics/signals/#sending-signals
Again, definitely recommend the first one in case of API changes. I can also recommend the second option just because allauth is pretty reputable and you know what going to happen without too huge of an package change, but you never know.
i use django cache system. I want to that when anyone update or insert model, django cache clean. I think, if i get this question's answer i can do it :) also i want to advice for fix this problem. Thank you.
My Example signal;
from django.core.cache import cache
#receiver(post_save, sender=ModelName)
def cache_celan(sender, created, instance, **kwargs):
print("anyone created something so i clean cache.")
cache.clear()
This nice way but i can use it for only model. Is possible i use for it all model?
Thank you.
I find this question's answer :)
if you use "None" for sender, signals detect all model.
from django.core.cache import cache
#receiver(post_save, sender=None)
def cache_celan(sender, created, instance, **kwargs):
print("anyone created or updated something so i clean cache.")
cache.clear()
I'm using Django Allauth. Users can either sign up using Google, Twitter, Facebook or they can sign up using their email address. Once signed up, their details will be stored in the User table. There's also another model I have called Profile that contains user information like bio, avatar, etc. I'd like to create a Profile for the user when they sign up. I looked at Allauth signals and found the user_signed_up signal to be appropriate. Here's how I wrote the code in my handlers.py file:
#receiver(user_signed_up)
def create_profile(request, user):
profile = Profile(avatar='img/blah/blah.jpg', bio='Example text', gender='M', dob='2018-01-01',
country='US', user=user)
profile.save()
I added random stuff just so I can see if it's being created or not, but for some reason when the user signs up their profile is not being created. What am I doing wrong?
You have to be sure you're importing the handlers.py module somehow in order to signal handler gets registered, you can write
import handlers
anywhere in your code, but the recommended place is in the ready method of your app config class.
References:
https://chriskief.com/2014/02/28/django-1-7-signals-appconfig/
https://docs.djangoproject.com/en/2.1/ref/applications/
You need to write signal when user model instance save signal will work there you need to write one condition this instance is new created or old modify base on this condition you can create profile
#receiver(post_save, sender=User)
def user_updated(sender, created=False, **kwargs):
user = kwargs.get('instance', None)
if user and created:
##create profile object here
I want to send an email with login details to user emailaddress whenever Admin adds new user to admin site.
I know Django provides send_mail module for that,but I don't know where should I put this code
and override some view to send automatic mails on new user addition.
from django.core.mail import send_mail
send_mail('Subject here', 'Here is the message.', 'from#example.com',
['to#example.com'], fail_silently=False)
How can i do it?
I tried putting this code in my models.py
from django.db.models.signals import post_save
from django.contrib.auth.models import User
def email_new_user(sender, **kwargs):
if kwargs["created"]: # only for new users
new_user = kwargs["instance"]
print new_user.email
#send_mail('Subject here', 'Here is the message.', 'from#example.com',['to#example.com'], fail_silently=False)
post_save.connect(email_new_user, sender=User)
But its not printing anything on command line. I think the function is not getting called whenever i create a new user.Don't know why?
There are multiple problems I can see in the code as I can see it, above.
First, the def email_new_user() is wrongly indented. If that is not a formatting error here, correct it.
new_user = kwargs.["instance"] is wrong syntax. It really should be kwargs["instance"]
And then, do you have an SMTP server running? Can you send email from the shell? If not, configure that and then try it again. It should work.
You want to hook the post_save signal for the User model.
One possible problem was, Django user cretion consists of two steps. First django asks for username, password and password confirmation, and when you press save (or save and continue edit) your save method fired without e-mail information. Since django will accept that request as a newly created record, your signal will fire for a record with no e-mail information...
If django handles admin save diffrently and do not mark a newly created record instance as created you shall not have any problem, but probably django will not do that.
UPDATE: Some possible reasons are:
You need django 1.3, so check your django version with python manage.py version and update it if required...
Best place for your your models.py files
You can put signal handling and registration code anywhere you like. However, you'll need to make sure that the module it's in gets imported early on so that the signal handling gets registered before any signals need to be sent. This makes your app's models.py a good place to put registration of signal handlers.
These are basic problems...
I am trying to create a custom signal for when the field auth_user.is_active becomes 1. I looked at Django's docs on signals, but was having trouble understanding how to implement custom signals.
When a user account becomes active, I want to execute the following function:
def new_user(sender, **kwargs)
profile = User.objects.get(id=user_id).get_profile()
return RecentActivity(content_object=profile, event_type=1, timestamp=datetime.datetime.now())
How would I do this. And also, what is the advantage of using signals over just doing the database insert directly? Thank you.
Here is what I did:
# in models.py
#receiver(pre_save, sender=User, dispatch_uid='get_active_user_once')
def new_user_activation_handler(sender, instance, **kwargs):
if instance.is_active and User.objects.filter(pk=instance.pk, is_active=False).exists():
profile = User.objects.get(pk=instance.pk).get_profile()
RecentActivity.objects.create(content_object=profile, event_type=1, timestamp=datetime.datetime.now())
If you want to do something when the field is changing, you can use the approach suggested by Josh, which is essentially to override the __init__ method.
Signals are generally used to communicate between apps. For example auth app sends user_logged_in signal. So if you want to do something when user is logging in, you just handle this signal, no need to patch the app.