Creating a Django Login Form
I wanted to discuss how to create a login-type app today. I’m working on a project for work and came across the need for a login page (well, and logout too). Now, while I may change this to the built-in method, I wanted to share the knowledge I gained in dealing with some oddities of the forms setup in general.
When you’re creating a login form, it’s generally best in my opinion to use the forms portion of Django instead of straight calls. It’s more DRY compliant, and you have a lot of stuff taken care of for you when it comes to the output. The problem I came across with was about data as it’s sent back.
So…I won’t concentrate much on how to use the forms setup (maybe I should create a tutorial maybe), but your general authentication setup may look something like mine:
def auth(request):
if request.method == ‘POST’:
form = LoginForm(request.POST, error_class=LoginErrorOverride)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return render_to_response(‘auth/loginsuccessful.html’)
else:
return render_to_response(‘auth/logindisabled.html’)
else:
form.errors['login'] = ‘unsuccessful’ #Adds an error, so we can raise it later.
form.data = {‘username’: form.data['username']} #Clear our data, except for the username.
else:
logout(request)
form = LoginForm()
return render_to_response(‘auth/login.html’, {‘form’: form})
So this basically tries to keep as little logic as possible needed for the forms. I create the object from my forms class, check validation, then check login. If it’s invalid, or if it’s an incorrect login, I want to redisplay the login web page with giving them a try again.
The problem I had was that reloading the page meant that the password was entered as a “default field”. Now…in my opinion, the password widget really should somehow override this behavior because it’s absolutely stupid. For the most part, password fields should really never be outputted back to the user. That’s where the line:
form.data = {‘username’: form.data['username']} #Clear our data, except for the username.
takes care of the situation. I’m not fond of this solution, but it does work. The optimal solution is that for a password widget, we should have it automatically clear the data for us.





