【问题标题】:why is the firstname and lastname field not saved in django-registration?为什么名字和姓氏字段没有保存在 django-registration 中?
【发布时间】:2014-04-29 08:41:57
【问题描述】:

我在django-registration 表单中包含了firstnamelastname 的字段。但是注册后我的admin page没有显示注册的first namelast name,它是空白的,但显示usernameemail address

请阅读下面source code 中提供的docstring

这是来自django-registrationRegistrationForm的代码

from django.contrib.auth.models import User
from django import forms
from django.utils.translation import ugettext_lazy as _

class RegistrationForm(forms.Form):
    """
    Form for registering a new user account.

    Validates that the requested username is not already in use, and
    requires the password to be entered twice to catch typos.

    Subclasses should feel free to add any additional validation they
    need, but should avoid defining a ``save()`` method -- the actual
    saving of collected user data is delegated to the active
    registration backend.

    """
    required_css_class = 'required'

    username = forms.RegexField(regex=r'^[\w.@+-]+$',
                                max_length=30,
                                label=_("Username"),
                                error_messages={'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")})
    email = forms.EmailField(label=_("E-mail"))
    password1 = forms.CharField(widget=forms.PasswordInput,
                                label=_("Password"))
    password2 = forms.CharField(widget=forms.PasswordInput,
                                label=_("Password (again)"))

    first_name=forms.RegexField(regex=r'^[\w.@+-]+$',
                                max_length=30,
                                label=_("first name"),
                                error_messages={'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")})
    last_name=forms.RegexField(regex=r'^[\w.@+-]+$',
                                max_length=30,
                                label=_("last name"),
                                error_messages={'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")})

    def clean_username(self):
        """
        Validate that the username is alphanumeric and is not already
        in use.

        """
        existing = User.objects.filter(username__iexact=self.cleaned_data['username'])
        if existing.exists():
            raise forms.ValidationError(_("A user with that username already exists."))
        else:
            return self.cleaned_data['username']

    def clean(self):
        """
        Verifiy that the values entered into the two password fields
        match. Note that an error here will end up in
        ``non_field_errors()`` because it doesn't apply to a single
        field.

        """
        if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
            if self.cleaned_data['password1'] != self.cleaned_data['password2']:
                raise forms.ValidationError(_("The two password fields didn't match."))
        return self.cleaned_data

编辑:

    def register(self, request, **cleaned_data):
            username, email, password,first_name,last_name = (cleaned_data['username'], cleaned_data['email'], cleaned_data['password1'],
                                        cleaned_data['first_name'],cleaned_data['last_name'])
            if Site._meta.installed:  # @UndefinedVariable
                site = Site.objects.get_current()
            else:
                site = RequestSite(request)
            new_user = RegistrationProfile.objects.create_inactive_user(username, email,
                                                                        password, site, first_name,last_name)
            signals.user_registered.send(sender=self.__class__,
                                         user=new_user,
                                         request=request)
            return new_user


def create_inactive_user(self, username, email, password,
                             site, send_email=True,first_name=None, last_name=None):
        new_user = User.objects.create_user(username, email, password)
        if first_name:
            new_user.first_name=first_name
        if last_name:
            new_user.last_name=last_name
        new_user.is_active = False
        new_user.save()

        registration_profile = self.create_profile(new_user)

        if send_email:
            registration_profile.send_activation_email(site)

        return new_user
    create_inactive_user = transaction.commit_on_success(create_inactive_user)

【问题讨论】:

  • 你使用的是什么版本的 Django?

标签: django django-admin django-registration django-users


【解决方案1】:

由于 teewuane 提到的更正后现在无法正常工作是因为method signature

考虑一下:

def create_inactive_user(self, username, email, password,
                         site, send_email=True, first_name=None, last_name=None):

但是在上面的register method你打个电话:

new_user = RegistrationProfile.objects.create_inactive_user(username, email, password, site, first_name, last_name)

因为send_email=Truedefault 的值,所以first_name 得到的任何东西都会作为send_email 传入,last_name 会传递给first_name。因此,您将拥有last_name 作为None

修复很简单。只需将方法签名更改如下:

def create_inactive_user(self, username, email, password,
                             site, first_name=None, last_name=None, send_email=True):

【讨论】:

    【解决方案2】:

    更新:

    您可以将Registration/Models.py 上的create_inactive_user 更改为如下所示...

    def create_inactive_user(self, username, email, password,
                             site, send_email=True, first_name=None, last_name=None):
        """
        Create a new, inactive ``User``, generate a
        ``RegistrationProfile`` and email its activation key to the
        ``User``, returning the new ``User``.
    
        By default, an activation email will be sent to the new
        user. To disable this, pass ``send_email=False``.
    
        """
        new_user = User.objects.create_user(username, email, password)
        new_user.is_active = False
        new_user.first_name = first_name
        new_user.last_name = last_name
        new_user.save()
    
        registration_profile = self.create_profile(new_user)
    
        if send_email:
            registration_profile.send_activation_email(site)
    
        return new_user
    

    请注意,它现在接受 first_namelast_name。还要注意new_user.first_name = first_namenew_user.last_name = last_name

    然后在 Registration/backends/default/views.py 上,您会希望 register 看起来像这样......

    def register(self, request, **cleaned_data):
    
        username, email, password, first_name, last_name = cleaned_data['username'], cleaned_data['email'], cleaned_data['password1'], cleaned_data['firstname'], cleaned_data['lastname']
        if Site._meta.installed:
            site = Site.objects.get_current()
        else:
            site = RequestSite(request)
        new_user = RegistrationProfile.objects.create_inactive_user(username, email, password, site, first_name, last_name)
        signals.user_registered.send(sender=self.__class__,
                                     user=new_user,
                                     request=request)
        return new_user
    

    注意firstname(这是您的表单获取它的方式)和first_name(这是存储的内容,然后传递给create_inactive_user

    【讨论】:

    • 正确,数据库已设置为保存名字和姓氏。此外,上面的答案假设您使用的是简单而不是默认值。你用的是哪一个?如果您没有在网址中指定“简单”。您很可能使用默认值。
    • 我使用的是默认值。但它有一个不同的电话,即new_user = RegistrationProfile.objects.create_inactive_user(username, email, password, site)
    • 哈哈,我从来没有对我的答案进行过这么多的修改。我再次更新了它,应该对你有用。
    • 我的姓氏没有在管理员中注册和显示(所以我猜它没有保存)。但名字已注册并显示在管理员上。我已经粘贴在上面的编辑中
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 2018-04-30
    • 2016-02-22
    • 2021-09-03
    • 1970-01-01
    相关资源
    最近更新 更多