django-registration-redux with custom user model r

2020-07-24 05:24发布

问题:

I am struggling with making my custom user model works with django-registration-redux. I manage to get all fields displaying propertly in registration view and i can create account within django shell. But when i try to register on page i get:

NotImplementedError at /accounts/register/
No exception message supplied
Request Method: POST
Request URL:    http://127.0.0.1/accounts/register/
Django Version: 1.9.2
Exception Type: NotImplementedError
Exception Location: /usr/local/lib/python3.5/site-packages/registration/views.py in register, line 118
Python Executable:  /usr/local/bin/python3.5
Python Version: 3.5.1
Python Path:    
['/opt/davinci/davinci-web',
 '/usr/local/bin',
 '/usr/local/lib/python35.zip',
 '/usr/local/lib/python3.5',
 '/usr/local/lib/python3.5/plat-linux',
 '/usr/local/lib/python3.5/lib-dynload',
 '/usr/local/lib/python3.5/site-packages']

my root.urls.py

from django.conf.urls import url, include
from django.contrib import admin

from home.views import home


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', home, name="home"),
    url(r'^booking/', include('booking.urls'), name="booking"),
    url(r'^accounts/', include('accounts.urls'), name='accounts')
]

accounts.urls

from django.conf.urls import url, include
from registration.views import RegistrationView

from .forms import UserRegistrationForm    

urlpatterns = [
    url(r'^register/$', RegistrationView.as_view(form_class=UserRegistrationForm),
        name='registration_register',),
    url(r'^', include('registration.backends.default.urls')),
]

accounts.models.py

from django.db import models

from django.utils import timezone
from django.core.mail import send_mail
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager


class UserManager(BaseUserManager):

    def _create_user(self, email, password, first_name, last_name,
                     is_staff, is_superuser, **extra_fields):
        now = timezone.now()
        if not email:
            raise ValueError(_('Email is required'))
        email = self.normalize_email(email)
        first_name = first_name.capitalize()
        last_name = last_name.capitalize()
        user = self.model(email=email, first_name=first_name, last_name=last_name,
                          is_staff=is_staff, is_active=False,
                          is_superuser=is_superuser, last_login=now, date_joined=now,
                          **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password, first_name, last_name, **extra_fields):
        return self._create_user(email, password, first_name, last_name, is_staff=False,
                                 is_superuser=False, **extra_fields)

    def create_superuser(self, email, password, first_name, last_name, **extra_fields):
        user = self._create_user(email, password, first_name, last_name, is_staff=True,
                                 is_superuser=True, **extra_fields)
        user.is_active = True
        user.save(using=self._db)
        return user


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(_('email'), max_length=100, unique=True,
                              help_text=_('Required. 100 characters or fewer. '
                                          'Letters, numbers and @/./+/-/_ characters'))
    first_name = models.CharField(_('first name'), max_length=30, blank=False, null=True)
    last_name = models.CharField(_('last name'), max_length=30, blank=False, null=True)
    is_staff = models.BooleanField(_('staff status'), default=False)
    is_active = models.BooleanField(_('active'), default=False)
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    objects = UserManager()

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('user')

    def get_full_name(self):
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        return self.first_name

    def email_user(self, subject, message, from_email=None):
        send_mail(subject, message, from_email, [self.email])

accounts.forms.py

from django import forms
from django.utils.translation import ugettext_lazy as _
from registration.forms import RegistrationForm
from .models import User


class UserRegistrationForm(RegistrationForm):
    first_name = forms.CharField(max_length=30, label=_("First name"))
    last_name = forms.CharField(max_length=30, label=_("Last name"))

    class Meta:
        model = User
        fields = ("email", "first_name", "last_name")

I suspect that i have to implement register method somewhere but no idea how i where. i found this answer but i can not figure out what to do whit it.

回答1:

Ok. I got it working. Posting solutions here for descendants. My accounts/views.py

from django.contrib.sites.shortcuts import get_current_site
from registration.backends.default.views import RegistrationView
from registration.models import RegistrationProfile
from registration import signals

from .forms import UserRegistrationForm
from .models import User


class UserRegistrationView(RegistrationView):
    form_class = UserRegistrationForm

    def register(self, request, form):

        site = get_current_site(request)

        if hasattr(form, 'save'):
            new_user_instance = form.save()
        else:
            new_user_instance = (User().objects
                                 .create_user(**form.cleaned_data))

        new_user = RegistrationProfile.objects.create_inactive_user(
            new_user=new_user_instance,
            site=site,
            send_email=self.SEND_ACTIVATION_EMAIL,
            request=request,
        )
        signals.user_registered.send(sender=self.__class__,
                                     user=new_user,
                                     request=request)
        return new_user

And in accounts/urls.py Change

from registration.views import RegistrationView

to

from .views import UserRegistrationView