Django:登录表单中的密码字段可选

时间:2011-09-16 09:24:27

标签: django django-forms

在我的注册中,用户可以根据需要创建没有密码的帐户。我希望登录表单中的密码字段是可选的。

我目前正在使用内置视图django.contrib.auth.views.login进行登录。此处的表单验证需要提交密码。

是否可以自定义/覆盖内置表单以允许可选地提交密码,如果是这样的话?显然,它仍将验证登录名,其中提供了用户名和密码,并且用户在注册时设置了密码。

由于

2 个答案:

答案 0 :(得分:3)

django.contrib.auth.views.logindjango docs)接受参数authentication_form。我会尝试将其子类化,并覆盖:

  • 密码字段,以便不需要
  • 无需密码处理用户的干净方法

我把干净的方法当作练习。使用AuthenticationForm code作为参考。您可能需要编写自己的authentication backend来验证没有密码的用户。

然后,您可以将身份验证表单作为参数传递到您的网址配置

中 祝你好运!

#urls.py
from django.contrib.auth.models.forms import AuthenticationForm
from django.utils.translation import ugettext_lazy as _

class MyAuthenticationForm(AuthenticationForm):
    password = forms.CharField(label=_("Password"), widget=forms.PasswordInput, required=False)

    def clean(self):
        # left as exercise

urlpatterns = patterns('',
   (r'^accounts/login/$', 'django.contrib.auth.views.login', {'authentication_form':MyAuthenticationForm}),
)

答案 1 :(得分:2)

感谢@Alasdair,这是一个很好的帮助。我发现我不需要编写自定义身份验证后端。对于可能需要它的任何其他人,完整的解决方案如下:

#forms.py
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate
from django.utils.translation import ugettext_lazy as _

class LoginForm(AuthenticationForm):
    username = forms.CharField(max_length=30)
    password = forms.CharField(widget=forms.PasswordInput, required=False)
    user_cache = None

    def clean(self):
        try:
            username = User.objects.get(username=self.cleaned_data['username']).username
        except User.DoesNotExist:
            raise forms.ValidationError(_("No such user registered."))

        self.user_cache = authenticate(username=username, password=self.cleaned_data['password'])
        if self.user_cache is None or not self.user_cache.is_active:
            raise forms.ValidationError(_("Username or password is incorrect."))
        return self.cleaned_data

    def get_user(self):
        return self.user_cache

#urls.py
from myapp.forms import LoginForm

urlpatterns = patterns('',
    ...
    url(r'^login/$', 'django.contrib.auth.views.login', {'authentication_form': LoginForm}),
    ...
)