如何为django-registration创建自定义django后端?

bha*_*ral 2 python django django-forms django-registration

我读过这个

http://docs.b-list.org/django-registration/0.8/backend-api.html

而且我已经开始制作自己的后端了.我这样做是因为我想创建一个不允许使用相同的电子邮件进行注册的后端,我想更改电子邮件错误消息.我也想加入我自己的领域!

这是我想出的:

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

class customRegistrationForm(RegistrationForm):
    email2 = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
        maxlength=75)),
        label=_("Confirm email"))

    def clean_email(self):
        """
        Validate that the email is alphanumeric and is not already
        in use.
        """
        try:
            email = User.objects.get(email__iexact=self.cleaned_data['email'])
        except User.DoesNotExist:
            return self.cleaned_data['email']
        raise forms.ValidationError(_("That email already exists - if you have forgotten your password, go to the login screen and then select \"forgot password\""))

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

        """
        if 'email' in self.cleaned_data and 'email2' in self.cleaned_data:
            if self.cleaned_data['email'] != self.cleaned_data['email2']:
                raise forms.ValidationError(_("The two email fields didn't match."))
        return super(RegistrationForm,clean)
Run Code Online (Sandbox Code Playgroud)

上面的内容在我的init .py文件中(不管是什么)

然后,我有我的urls.py代码:

url(r'^accounts/register/$',
    register,
        { 'backend': 'myapp.forms.customRegistrationForm' },
    name='registration_register'),
... #other urls here!
Run Code Online (Sandbox Code Playgroud)

现在,当我进入/ accounts/register页面时,我收到以下错误:

/ accounts/register /的AttributeError

'customRegistrationForm'对象没有属性'registration_allowed'

这很奇怪.它似乎在告诉我,我需要在我的子类中添加一个"registration_allowed"方法.但是,子类是RegistrationForm的子类,它工作正常并且没有定义那些东西......我知道我可以添加这些成员,但它似乎超出了扩展的目的,对吧?

UPDATE

这是现在它的代码!

我将不同的类分解为不同的文件夹中的不同init .py文件 - 一个名为"forms",一个名为"backends",两者都位于我的主项目下的"djangoRegistration"文件夹中.

/ forms/init .py

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

class customRegistrationForm(RegistrationForm):
    def __init__(self, *args, **kw):
        super(RegistrationForm, self).__init__(*args, **kw)
        self.fields.keyOrder = [
            'username',
            'email',
            'email2',
            'password1',
            'password2'
        ]

    email2 = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict,
        maxlength=75)),
        label=_("Confirm email"))

    def clean_email(self):
        """
        Validate that the email is alphanumeric and is not already
        in use.
        """
        try:
            email = User.objects.get(email__iexact=self.cleaned_data['email'])
        except User.DoesNotExist:
            return self.cleaned_data['email']
        raise forms.ValidationError(_("That email already exists - if you have forgotten your password, go to the login screen and then select \"forgot password\""))

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

        """
        if 'email' in self.cleaned_data and 'email2' in self.cleaned_data:
            if self.cleaned_data['email'] != self.cleaned_data['email2']:
                raise forms.ValidationError(_("The two email fields didn't match."))
        return super(RegistrationForm,clean)
Run Code Online (Sandbox Code Playgroud)

/ backends/init .py

from registration.backends.default import DefaultBackend
from dumpstownapp.djangoRegistration.forms import customRegistrationForm

class customDefaultBackend(DefaultBackend):
    def get_form_class(self, request):
        """
        Return the default form class used for user registration.

        """
        return customRegistrationForm
Run Code Online (Sandbox Code Playgroud)

最后,我的urls.py只引用了新的后端:

url(r'^accounts/register/$',
    register,
        { 'backend': 'myapp.djangoRegistration.backends.customDefaultBackend' },
    name='registration_register'),
#more urls here! yay!
Run Code Online (Sandbox Code Playgroud)

作为最后一点,我必须添加一些代码来"命令"字段的呈现方式,这就是customRegistrationForm中的init方法正在做的事情

谢谢!

Dan*_*man 7

你试图使用一个表单作为后端,但这不是后端的根本.正如您链接到的文档所解释的那样,后端是一个实现某些方法的类,包括registration_allowed.表单没有实现任何这些,这并不奇怪,因为它用于用户输入和验证,而不是后端操作.

但是,该页面确实提供了实现此方法的正确方法的提示.后端可以定义的方法之一是get_form_class()返回要使用的表单类.所以,你需要的是一个自定义后端,它继承registration.backends.default.DefaultBackend并覆盖只get_form_class返回的方法customRegistrationForm.