I'm using Allauth module for create accounts and signing in. But I'm also need to create a new directory for every user, who makes an account.
I know that I need to use Signals some how... But cant find a start point for that.
Am I need to create new model, view or whatever? Or what I need to do to complete this task?
You need a post_save signal for the User model.
from django.db.models.signals import post_save
from django.contrib.auth.models import User
def create_folder(sender, instance, created, **kwargs):
if not created: # if it's not a new object return
return
# do your stuff
post_save.connect(create_folder, sender=User)
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'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' m using django-allauth to authenticate users from different social sites. When a User is created in my db, i' d like to call a function which would create a UserProfile (or would do something) and to achieve this the best would be to use signals.post_save .
I' ve multiple django applications and of course i don' t want to change the core django-allauth, so my question where do i place my post_save code?
Thanks.
You could create an accounts app locally to hold the UserProfile and everything associated with it. The you could have:
# Connecting to AllAuth Signals
from allauth.account.signals import user_signed_up
from django.dispatch import receiver
#receiver(user_signed_up)
def new_user_signup(sender, **kwargs):
p = UserProfile(user = kwargs['user'])
p.save()
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')
I've been struggling with this problem for 5 hours and I have a feeling it's a simple solution that I'm just overlooking.
I'm trying to tie in a third party module (Django Activity Stream) that uses a series of senders and receivers to post data about user activity to a database table. Everything is set up and installed correctly, but I get a 'Signal' Object has No Attribute 'Save' error when I try to run it.
I suspect the problem is in my syntax somewhere. I'm just getting started with Signals, so am probably overlooking something a veteran will spot immediately.
In views.py I have:
from django.db.models.signals import pre_save
from actstream import action ##This is the third-party app
from models import Bird
def my_handler(sender, **kwargs):
action.save(sender, verb='was saved')
#return HttpResponse("Working Great")
pre_save.connect(my_handler, sender=Bird)
def animal(request):
animal = Bird()
animal.name = "Douglas"
animal.save()
The Django Activity Stream app has this signals.py file:
from django.dispatch import Signal
action = Signal(providing_args=['actor','verb','target','description','timestamp'])
And then this models.py file:
from datetime import datetime
from operator import or_
from django.db import models
from django.db.models.query import QuerySet
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.timesince import timesince as timesince_
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.models import User
from actstream import action
...
def action_handler(verb, target=None, **kwargs):
actor = kwargs.pop('sender')
kwargs.pop('signal', None)
action = Action(actor_content_type=ContentType.objects.get_for_model(actor),
actor_object_id=actor.pk,
verb=unicode(verb),
public=bool(kwargs.pop('public', True)),
description=kwargs.pop('description', None),
timestamp=kwargs.pop('timestamp', datetime.now()))
if target:
action.target_object_id=target.pk
action.target_content_type=ContentType.objects.get_for_model(target)
action.save()
action.connect(action_handler, dispatch_uid="actstream.models")
Your main problem is in the discipline in maintaining coding style, or rather in this case, lack of. You will find that it is easier to identify problems in your code if you do not use the same name to refer to multiple things within the same module; give each object a unique, meaningful name, and refer to it using only that name.
The bottom line here is that the docs for that project contain bad code. This line:
action.save(sender, verb='was saved')
isn't ever going to work. The from actstream import action ultimately imports a signal from actstream.signals, and signals do not and never have had a save method. Especially not with such an odd signature of sender, verb.
At first I thought maybe the author had done something odd with subclassing Signal, but after looking at the rest of the codebase, that's just not the case. I'm not entirely sure what the intention of those docs was supposed to be, but the right thing to do in your handler will either be to save a new Action (imported from actstream.models) instance, or to do something with your model.
Sadly, the project's repository has a pretty sorry set of tests/examples, so without downloading and trying the app myself, I can't tell you what needs to happen there. You might try contacting the author or simply try finding a better-documented/better-maintained Activity Streams app.