I’ve got a Django-based site that allows users to register (but requires an admin to approve the account before they can view certain parts of the site). I’m basing it off of django.contrib.auth. I require users to register with an email address from a certain domain name, so I’ve overridden the UserCreationForm‘s save() and clean_email() methods.
My registration page uses the following view. I’m interested in hearing about how I might improve this view—code improvements or process improvements (or anything else, really).
def register(request): if request.method == 'POST': form = UserCreationForm(request.POST) if form.is_valid(): message = None form.save() username = form.cleaned_data['username'] password = form.cleaned_data['password1'] user = authenticate(username=username, password=password) first_name = form.cleaned_data['first_name'] last_name = form.cleaned_data['last_name'] email = user.email # If valid new user account if (user is not None) and (user.is_active): login(request, user) message = '<strong>Congratulations!</strong> You have been registered.' # Send emails try: # Admin email pk = None try: pk = User.objects.filter(username=username)[0].pk except: pass admin_email_template = loader.get_template('accounts/email_notify_admin_of_registration.txt') admin_email_context = Context({ 'first_name': first_name, 'last_name': last_name, 'username': username, 'email': email, 'pk': pk, }) admin_email_body = admin_email_template.render(admin_email_context) mail_admins('New User Registration', admin_email_body) # User email user_email_template = loader.get_template('accounts/email_registration_success.txt') user_email_context = Context({ 'first_name': form.cleaned_data['first_name'], 'username': username, 'password': password, }) user_email_body = user_email_template.render(user_email_context) user.email_user('Successfully Registered at example.com', user_email_body) except: message = 'There was an error sending you the confirmation email. You should still be able to login normally.' else: message = 'There was an error automatically logging you in. Try <a href=\'/login/\'>logging in</a> manually.' # Display success page return render_to_response('accounts/register_success.html', { 'username': username, 'message': message, }, context_instance=RequestContext(request) ) else: # If not POST form = UserCreationForm() return render_to_response('accounts/register.html', { 'form': form, }, context_instance=RequestContext(request) )
You don’t even need this code, but I think the style:
is more naturally written like:
and then in your admin notify template use
{{ user.id }}instead of{{ pk }}.But, like I said, you don’t need that code at all because you already have a user object from your call to
authenticate().Generally in Python, it’s considered poor practice to have the exception handler in a try/except block be empty. In other words, always capture a specific exception such as
User.DoesNotExistfor this case.It’s also poor practice to have many lines inside the
trypart of the try/except block. It is better form to code this way:A final, minor, recommendation is to not send the email directly in your view because this won’t scale if your site starts to see heavy registration requests. It is better add in the django-mailer app to offload the work into a queue handled by another process.