2

我读过这个

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”中。

/forms/初始化.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方法正在做的事情

谢谢!

4

1 回答 1

7

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

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

于 2012-05-09T13:51:22.023 回答