【问题标题】:django-registration 1.0 saving custom user fieldsdjango-registration 1.0 保存自定义用户字段
【发布时间】:2013-06-27 05:19:39
【问题描述】:

我一直在尝试将 django-registration 与自定义用户一起使用,但无法解决一个小问题。我向用户添加了一个附加字段,该字段显示在注册表单上,但无法保存任何数据。以下是相关代码:

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 保存额外的自定义用户字段吗?任何想法/建议/解决方案都有帮助!!

【问题讨论】:

    标签: django django-registration


    【解决方案1】:

    好吧,我想出了一个解决方案,尽管是一个粗略的解决方案。如果其他人在向 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) 更新你的 urls 文件:

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

    希望有人在某个地方能从中得到一些用处。姜戈快乐!

    【讨论】:

      【解决方案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 的答案,因此我将上述内容作为单独的答案发布。

      【讨论】:

        猜你喜欢
        • 2014-12-25
        • 2013-07-28
        • 2010-12-26
        • 2011-02-25
        • 1970-01-01
        • 1970-01-01
        • 2014-02-15
        • 2013-05-05
        • 2011-06-23
        相关资源
        最近更新 更多