django-registration 1.0保存自定义用户字段

时间:2013-06-29 15:04:27

标签: django django-registration

我一直在尝试使用自定义用户进行django-registration,但无法解决一个小问题。我在注册表单上向User添加了一个附加字段,但是无法保存任何数据。这是相关的代码:

models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

class eduuser(AbstractUser):
   USER_TYPE_CHOICES = (
      #Choices
)
   user_type = models.CharField(max_length=3, choices=USER_TYPE_CHOICES)

forms.py

from registration.forms import RegistrationForm
from django import forms
from django.forms import ModelForm
from .models import eduuser

class eduuserForm(forms.ModelForm):
    class Meta:
        model = eduuser
        fields = ('user_type',)

RegistrationForm.base_fields.update(eduuserForm.base_fields)


class CustomRegistrationForm(RegistrationForm):
    def save(self, profile_callback=None):
        user = super(CustomRegistrationForm, self).save(profile_callback=None)
        edu, c = eduuser.objects.get_or_create(user=user, \
            user_type=self.cleaned_data['user_type'])

urls.py

from posts.forms import CustomRegistrationForm

urlpatterns = patterns('',
    url(r'^accounts/register/$', RegistrationView.as_view(
        form_class=CustomRegistrationForm)),
)

问题似乎在forms.py文件中,特别是“CustomRegistrationForm”类。这个想法来自this帖子,这是为django-registration 0.8。

无论如何,有没有人知道如何使用django-registration 1.0保存额外的自定义用户字段?任何想法/建议/解决方案都有帮助!!

2 个答案:

答案 0 :(得分:2)

嗯,我找到了一个解决方案,尽管是一个粗糙的解决方案。如果其他人在添加&将额外的用户字段保存到django-registration 1.0提供的注册页面,希望这会有所帮助...(虽然我不能保证这对你有效)

1)在应用中创建一个新的用户模型,添加一个额外的字段:

# posts/models.py
from django.contrib.auth.models import AbstractUser

class eduuser(AbstractUser):
    # Created USER_TYPE_CHOICES, omitted here due to length
    user_type = models.CharField(max_length=3, choices=USER_TYPE_CHOICES)

2)将用户模型添加到您的设置文件中。我的应用程序恰好被称为“帖子”,因此我的用户模型是:

# appName/settings.py
AUTH_USER_MODEL = "posts.eduuser"

3)调整django-registration以处理新的用户模型。我做了改变here。如果你碰巧在另一个项目中使用它,这不应该影响django-registration的功能。

4)将额外的字段添加到表单中:

# posts/forms.py
from registration.forms import RegistrationForm
from django import forms
from django.forms import ModelForm
from .models import eduuser


class eduuserForm(forms.ModelForm):
    """
    Get extra 'user_type' field to add to form for django-registration
    """
    class Meta:
        model = eduuser
        fields = ('user_type',)

RegistrationForm.base_fields.update(eduuserForm.base_fields)

5)覆盖RegistrationView。我不完全确定为什么这是必要的,但没有它我会得到错误。我相信它会说,“嘿模特,要为额外的领域做好准备”。 这基本上是从registration / backends / default / views.py复制/粘贴的,但是用 额外的字段添加

# posts/views.py
from registration.backends.default.views import RegistrationView
from registration import signals
from registration.models import RegistrationProfile
from django.contrib.sites.models import Site
from django.contrib.sites.models import RequestSite

class CustomRegistrationView(RegistrationView):
    """
    Needed override this django-registration feature to have it create
    a profile with extra field
    """
    def register(self, request, **cleaned_data):
        username, email, password, user_type = cleaned_data['username'], cleaned_data['email'], cleaned_data['password1'], cleaned_data['user_type']
        if Site._meta.installed:
            site = Site.objects.get_current()
        else:
            site = RequestSite(request)
        new_user = RegistrationProfile.objects.create_inactive_user(
            username, email, password, user_type, site)
        signals.user_registered.send(sender=self.__class__,
                                     user=new_user,
                                     request=request)
    return new_user

6)更新模型。我通过直接编辑django-registration模型来做到这一点(因为它是一个孤狼项目,这是我唯一的用途),但如果你使用django-registration进行其他任何操作,请不要这样做。您可以尝试覆盖您的应用中的模型。无论如何,在registration / models.py中我添加了额外的字段:

# registration/models.py
def create_inactive_user(self, username, email, password, user_type,
                         site, send_email=True):
    """
    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 = get_user_model().objects.create_user(username, email, password, user_type=user_type)
    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

7)更新你的网址文件:

#appName/urls.py
urlpatterns = patterns('',
    url(r'^accounts/register/$', CustomRegistrationView.as_view(
    form_class=RegistrationForm)),
)

希望有人能在某处得到一些用处。快乐的Django-ing!

答案 1 :(得分:2)

似乎不再需要chipperdrew的答案中的第3步。我发现django-registration的代码已经包含了导入get_user_model()的步骤。这对于django-registration v1.0

来说是正确的

在registration / models.py第15-19行

try:
    from django.contrib.auth import get_user_model
    User = get_user_model()
except ImportError:
    from django.contrib.auth.models import User

注意:我似乎无法直接评论chipperdrew的答案,所以我将上面的内容作为单独的答案发布。