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

时间:2012-05-09 13:44:17

标签: 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)

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

然后,我的urls.py代码:

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

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

  

/ accounts / register /

中的AttributeError      

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

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

更新

以下是现在的代码!

我将不同的类分解为不同文件夹中不同的 init .py文件 - 一个名为“表单”,一个名为“后端”,两者都位于我的“djangoRegistration”文件夹下主要项目。

/形式/的初始化的.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)

/后端/的初始化的.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

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

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

作为最后一点,我必须添加一些代码来“排序”字段的显示方式,这就是customRegistrationForm中的 init 方法正在做什么

谢谢!

1 个答案:

答案 0 :(得分:7)

您尝试使用表单作为后端,但这根本不是后端。如您链接的文档所述,后端是实现某些方法的类,包括registration_allowed。表单并没有实现任何这些,这并不奇怪,因为它意味着用户输入和验证,而不是后端操作。

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