django-registration auto create UserProfile

2019-03-16 01:08发布

I'm using django-registration and I'm trying to connect to its signals to automatically create a UserProfile.

Signal definition:

from django.dispatch import Signal

# A new user has registered.
user_registered = Signal(providing_args=["user", "request"])

Signal send by django-registration:

    def register(self, request, **kwargs):
    """
    Create and immediately log in a new user.

    """
    username, email, password = kwargs['username'], kwargs['email'], kwargs['password1']
    User.objects.create_user(username, email, password)

    # authenticate() always has to be called before login(), and
    # will return the user we just created.
    new_user = authenticate(username=username, password=password)
    login(request, new_user)
    signals.user_registered.send(sender=self.__class__,
                                 user=new_user,
                                 request=request)
    return new_user

My signal connect:

from registration.signals import *
from core.models import UserProfile
from django.contrib.auth.models import User

def createUserProfile(sender, instance, **kwargs):
    UserProfile.objects.get_or_create(user=instance)

user_registered.connect(createUserProfile, sender=User)

Needless to say no UserProfile is being created. What am I missing here?

Thanks a lot!

EDIT: I moved my connect() and its corresponding method to a model.py and still no luck.

New code:

from django.db import models

from django.contrib import auth
from django.contrib.auth import login
from core.forms import AuthForm
from registration.signals import *
from django.contrib.auth.models import User


# Create your models here.

class UserProfile(models.Model) :
    user = models.ForeignKey(User, unique=True)

    def __unicode__(self):
        return self.user.username


def createUserProfile(sender, instance, **kwargs):
    print "creating profile"
    UserProfile.objects.get_or_create(user=instance)

user_registered.connect(createUserProfile, sender=User)

I'm using Pycharm to debug, and in the very beginning my breakpoint on user_registered.connect() is hit. So I assume that connect() is being registered correctly. However, I still don't see createUserProfile being run. Anything else I'm missing?

Thanks!

ANSWER: Doh. My connect and receiver code was wrong. Correct code:

def createUserProfile(sender, user, request, **kwargs):
UserProfile.objects.get_or_create(user=user)

user_registered.connect(createUserProfile)

Realized it after I read signals.py in django-registration

2条回答
聊天终结者
2楼-- · 2019-03-16 01:52

Torsten is right: the alternative way is to use decorators as stated in documentation:

    from registration.signals import user_registered
    # ...
    @receiver(user_registered)
    def your_function_name_here(sender, user, request, **kwargs):
            # your code here
            pass

I like this way because it's compact and readable.

查看更多
smile是对你的礼貌
3楼-- · 2019-03-16 02:00

You need to register (connect) your signal in a module which is imported on server startup. Your file where user_registered.connect(createUserProfile, sender=User)lives is mot likely not imported on startup. From the django docs:

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.

http://docs.djangoproject.com/en/dev/topics/signals/#connecting-receiver-functions

So models.py of your custom app would be a good place (or any other module which is definitely imported on server startup).

查看更多
登录 后发表回答