覆盖auth模块AuthenticationForm以允许通过电子邮件登录

时间:2011-07-25 09:14:28

标签: python django inheritance django-forms django-authentication

我想让我的用户能够通过电子邮件登录。我已经看到了通过编写自定义身份验证后端来实现此目的的示例。但是,我希望通过继承django.contrib.auth.forms.AuthenticationForm并添加一个名为email的新字段来执行此操作,该字段在clean_email方法中从User模型中提取用户名,然后将其传递给父表格。

我已经尝试过这样做,但我失败了,因为我似乎无法修改请求或填充字段值。这就是我到目前为止所得到的。

class LoginForm(AuthenticationForm):
    email = forms.EmailField(
        required=True, label=_("Email")
    )

    def __init__(self, request=None, *args, **kwargs):
        super(LoginForm, self).__init__(
            request, *args, **kwargs
        )
        self.fields['username'].widget = forms.widgets.HiddenInput()

    def clean_email(self):
        user = User.objects.filter(email=self.cleaned_data['email'])
        if user:
            #self.fields['username'].value = user.username
            #return user.email
        else:
            raise forms.ValidationError(_("Incorrect email or password."))

感谢。

2 个答案:

答案 0 :(得分:1)

如果要修改其他字段,则应使用clean

def clean(self):
    cleaned_data = self.cleaned_data
    user = User.objects.filter(email=cleaned_data['email'])
    if user:
        cleaned_data['username'] = user.username
    else:
        raise forms.ValidationError(_("Incorrect email or password."))
    return cleaned_data

不要忘记,电子邮件在Django auth中并不是唯一的。

答案 1 :(得分:0)

您可以尝试这样的事情(未经测试):

class LoginForm(AuthenticationForm):
    def __init__(self, *args, **kwargs):
        super(LoginForm, self).__init__(*args, **kwargs)
        self.fields['username'].label = u'E-mail'

    def clean_username(self):
        # get user from e-mail address, minding possible exceptions
        return user.username