开发者

Django: password field optional in login form

开发者 https://www.devze.com 2023-04-05 02:45 出处:网络
In my regist开发者_运维技巧ration, a user can create an account with no password if they wish. I would like the password field in a login form to be optional.

In my regist开发者_运维技巧ration, a user can create an account with no password if they wish. I would like the password field in a login form to be optional.

I am currently using the built in view django.contrib.auth.views.login for logins. The form validation in this requires a password to be submitted.

Is it possible to customize/override the built in form to allow passwords to be submitted optionally, if so how? Obviously it will still validate a login where both a username and password is provided and the user has set a password at registration.

Thanks


django.contrib.auth.views.login (django docs) takes a parameter authentication_form. I would try subclass it, and override:

  • the password field so that it is not required
  • the clean method to handle users without a password

I've left the clean method as a exercise. Use the AuthenticationForm code as a reference. You may need to write your own authentication backend that authenticates users without passwords.

You can then pass your authentication form as a parameter in your url config,

Good luck!

#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}),
)


Thanks @Alasdair that was a great help. I discovered I did not need to write a custom authentication backend. Full solution is below for anyone else who might need it:

#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}),
    ...
)
0

精彩评论

暂无评论...
验证码 换一张
取 消