使用子类 RegistrationView 时,django-registration 似乎缩短了散列密码

django-registration seems to be shortening hashed password when using subclassed RegistrationView

我正在尝试设置带有一两个额外字段的 django 注册表单。我已经阅读了文档并搜索了 Whosebug。我遇到一个问题,用户在新字段中注册,但当我尝试登录时,它无法识别密码。

我创建了一个新视图(我刚刚从 django-registration 中剪切并粘贴了寄存器,因为我最初只想要它 运行):

class MyRegistrationView (RegistrationView):
    form_class = UserRegForm

    def register(self, form):
        new_user = RegistrationProfile.objects.create_inactive_user(
            form,
            site=get_current_site(self.request)
        )
        signals.user_registered.send(sender=self.__class__,
                                     user=new_user,
                                     request=self.request)
        return new_user

它使用这种形式:

class UserRegForm(RegistrationForm):
    CHOICES = Institution.objects.all().order_by('name')

    institution=forms.ChoiceField(choices=( (x.id, x.name) for x in CHOICES ),
                                  required = True)

这些是额外的模型:

class Institution(models.Model):
    name = models.CharField(max_length=200)

    def __unicode__(self):
        return u'%s' % (self.name)

class UserProfile(models.Model):
    user=models.OneToOneField(User, on_delete=models.CASCADE)
    institution=models.ForeignKey(
        Institution,
        null=True,
        blank=True)

    def __unicode__(self):
        return u'%s' % (self.user)

我的URL

url(r'^register', views.MyRegistrationView.as_view(form_class=UserRegForm), name='registration_register'),

我添加了这个来保存数据:从模型导入 UserProfile 从表单导入 UserRegForm

def user_created(sender, user, request, **kwargs):
    form = UserRegForm(request.POST)

    try: data = UserProfile.objects.get(user=user)
    except: data = UserProfile(user=user)
    data.institution = form.data["institution"]
    data.save()

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

一切正常,因为用户已注册,发送了一封电子邮件,机构已保存到用户配置文件中,但是当我尝试使用新用户登录(已激活帐户)时,它告诉我用户名和密码不匹配。

当我查看数据库时,散列的 paasword 字符串似乎比管理员(使用 manage.py createsuperuser 设置)短 10 个字符,所以我正在做一些我不应该做的事情或没有做我应该做的事情。

不胜感激。

我通过基本上将所有 RegistrationView 复制到 MyRegistrationView 来解决这个问题。现在登录工作正常。我不确定为什么这是必要的。

from registration.backends.model_activation.views import RegistrationView
from registration.models import RegistrationProfile
from registration import signals
from django.contrib.sites.shortcuts import get_current_site
from django.core import signing
from django.template.loader import render_to_string
from django.conf import settings
REGISTRATION_SALT = getattr(settings, 'REGISTRATION_SALT', 'registration')

class MyRegistrationView (RegistrationView):
    form_class = UserRegForm
    email_body_template = 'registration/activation_email.txt'
    email_subject_template = 'registration/activation_email_subject.txt'

    def register(self, form):
        new_user = self.create_inactive_user(form)
        signals.user_registered.send(sender=self.__class__,
                                     user=new_user,
                                     request=self.request)
        return new_user

    def get_success_url(self, user):
        return ('registration_complete', (), {})

    def create_inactive_user(self, form):
        """
        Create the inactive user account and send an email containing
        activation instructions.

        """
        new_user = form.save(commit=False)
        new_user.is_active = False
        new_user.save()

        self.send_activation_email(new_user)

        return new_user

    def get_activation_key(self, user):
        """
        Generate the activation key which will be emailed to the user.

        """
        return signing.dumps(
            obj=getattr(user, user.USERNAME_FIELD),
            salt=REGISTRATION_SALT
        )

    def get_email_context(self, activation_key):
        """
        Build the template context used for the activation email.

        """
        return {
            'activation_key': activation_key,
            'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
            'site': get_current_site(self.request)
        }

    def send_activation_email(self, user):
        """
        Send the activation email. The activation key is simply the
        username, signed using TimestampSigner.

        """
        activation_key = self.get_activation_key(user)
        context = self.get_email_context(activation_key)
        context.update({
            'user': user
        })
        subject = render_to_string(self.email_subject_template,
                                   context)
        # Force subject to a single line to avoid header-injection
        # issues.
        subject = ''.join(subject.splitlines())
        message = render_to_string(self.email_body_template,
                                   context)
        user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)

剩下的问题是它只是重新加载注册页面而不是完成注册吗?