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}),
...
)
精彩评论