如何将字段添加到Django User模型并使用django-registration在注册表单上显示?

时间:2014-03-21 17:48:22

标签: django django-forms django-users

我注意到Django提供的User model没有Date of Birth Field。 我不想自己编写custom User class来包含此attribute。我想知道是否有可能以某种方式来附加" date of birth User model。如果没有,那么使其工作的其他简单选项是什么。我也可以将User Model的内容保存到profile model并附加date of birth信息。

但我的form是否必须同时保存User and profile model我感到困惑的是如何工作。

编辑2 :(实施frnhr'解决方案后):

两个问题:activation email中未发送development server。我使用default User model尝试了django-registration,我看到activation email被发送出去了。但现在,custom user model发送no activation email

当我loginadminhttp://127.0.0.1:8000/admin/时,我看不到User model,只有registration profilesGroups。当我点击registration profiles时,它不会显示有关User的所有信息,只显示usernameactivation key已显示已过期的信息。附件是screenshot。怎么解决这个问题? enter image description here

enter image description here

2 个答案:

答案 0 :(得分:3)

在较新版本的Django中,制作自己的自定义用户模型非常轻松。有关详细信息,请参阅此答案:https://stackoverflow.com/a/16125609/236195

如果您使用的某些较旧的第三方应用程序具有硬编码为auth.models.User的模型关系,则可能会遇到问题。大多数持续开发的第三方应用程序可能已经或很快就会切换。


编辑 - 让它与django-registration

一起使用

<强>的myapp / models.py:

from django.contrib.auth.models import AbstractUser
from django.db import models
from django.utils.translation import ugettext_lazy as _

class CustomUser(AbstractUser):
    age = models.PositiveIntegerField(_("age"), null=True)  # this field is added to default User model

<强> settings.py:

INSTALLED_APPS = (
    # ...

    'registration_defaults',
    'registration',

    'myapp',
)

# ...

AUTH_USER_MODEL = "myapp.CustomUser"
ACCOUNT_ACTIVATION_DAYS = 2  # or something

urls.py (添加此行)

   url(r'^accounts/', include('registration.backends.default.urls')),

myapp / admin.py (可选)

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext_lazy as _

from .models import CustomUser


class CustomUserAdmin(UserAdmin):
    fieldsets = (
        (None, {'fields': ('username', 'password')}),
        (_('Personal info'), {'fields': ('first_name', 'last_name', 'email', 'age')}),  # added "age" field
        (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
                                       'groups', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )


admin.site.register(CustomUser, CustomUserAdmin)

<强> django的注册

从这里获取它:https://bitbucket.org/fhrzenjak/django-registration并将其放在项目文件夹中。

免责声明:这是我原来的django-registration repo的分支,mrginglymus为自定义用户模型应用了补丁:https://bitbucket.org/ubernostrum/django-registration/pull-request/30/django-15-compatibility-with-custom-user/diff

Django-registration-defaults是这里的默认模板的集合:https://github.com/yourcelf/django-registration-defaults它是可以安装pip的

编辑2 - 在注册时接受自定义字段

嗯,这是一个单独的问题,但这里的确如此......

创建MyRegistrationForm表单:

from registration.forms import RegistrationForm

class MyRegistrationForm(RegistrationForm):
    age = forms.CharField(required=False)

在你的urls.py中,在django-registration include之前添加一行。这将覆盖包含中的任何内容:

url(r'^accounts/register/$',
        RegistrationView.as_view(form_class=MyRegistrationForm),
        name='registration_register',
    ),
url(r'^accounts/', include('registration.backends.default.urls')),

修改自定义用户模型以响应user_registered信号并保存其他数据:

class CustomUser(AbstractUser):
    age = models.PositiveIntegerField(_("age"), null=True)

    @classmethod
    def user_created(cls, sender, user, request, **kwargs):
        from myapp.forms import MyRegistrationForm
        form = MyRegistrationForm(request.POST)
        user.age = form.data.get('age', None)
        user.save()
        pass

from registration.signals import user_registered
user_registered.connect(CustomUser.user_created)

答案 1 :(得分:1)

您最好的选择可能是继续创建自定义用户模型(您可以继承django.contrib.auth.models.AbstractUser并添加您想要的任何字段。)

关于以单一形式处理多个模型,实际上非常简单。您实际上想要使用多个Form,但在同一个<form>元素中渲染它们,并在视图中单独处理它们。

另一种方法是创建单个Form(可能不是ModelForm),其中包含您想要的所有字段。然后,在表单上编写save方法,创建/更新相关模型。这使得您的视图和模板代码比上面的方法更简单。

例如,这是一个表单类,它允许现有用户更改其电子邮件地址和出生日期。请注意,在调用User时,您会从视图中传递登录的save()

class UserEditForm(forms.Form):
    email = forms.EmailField()
    date_of_birth = forms.DateField()

    def save(self, user):
        user.email = self.cleaned_data['email']
        user.save()
        user.userprofile.date_of_birth = self.cleaned_data['date_of_birth']
        user.userprofile.save()

请注意,假设您拥有UserProfile模型,该模型与User具有一对一字段。