Django Registration
August 26, 2011
I'm using django-registration and I wanted to add a checkbox to the registration form which would indicate whether the user registering was a teacher or not. This value would then be stored on the user profile.
I took the opportunity to work out how to do this without modifying the provided django-registration source code.
urls.py
I copied in the contents of url.py from django-registration (registration/backends/default/urls.py) into my main project's urls.py file. At the same time I passed a new form into the /accounts/register endpoint, and I also referred to a local view for this functionality, rather than using the one supplied with django-registration:
from progperc.users.views import register url(r'^accounts/register/$', register, { 'backend': 'registration.backends.default.DefaultBackend', 'form_class' : RegistrationForm }, name='registration_register'),
forms.py
This form was imported direct from my project, and contained the following definition:
from django import forms from registration import forms as registrationforms from django.utils.translation import ugettext_lazy as _ class RegistrationForm(registrationforms.RegistrationForm): """ Form for user registration - adds checkbox to indicate you're a teacher """ is_teacher = forms.BooleanField(required=False, widget=forms.CheckboxInput(), label=_(u'I teach drums/percussion')) def clean_email(self): """ Query botscout to see if the email address is from a bot. """ lEmail = self.cleaned_data['email'] lConnection = httplib.HTTPConnection("botscout.com") lHeaders = {"Host" : "botscout.com", "User-Agent" : "Django", "Content-type": 'text/xml; charset="UTF-8"', "Content-length": "0", } lConnection.request("GET", "/test/?mail=%s" % lEmail, None, lHeaders) lResponseObject = lConnection.getresponse() lStatusCode = lResponseObject.status lResponse = lResponseObject.read() if lStatusCode == 200 and len(lResponse) > 0 and lResponse[0] == 'Y': raise forms.ValidationError("""Your email address appears on a bot register. If you are a real person, then please contact us via the feedback form and let us know.""") if len(lResponse) > 0 and lResponse[0] == '!': lErrorMessage = "Problems Accessing BotScout, %s:%s" % (lStatusCode, lResponse) send_mail('%s BotScout Error' % settings.EMAIL_SUBJECT_PREFIX, lErrorMessage, 'from@mail.com', ['to@mail.com'], fail_silently=True) return lEmail
Note that we've implemented clean_email
to check the applicant against the botscout database.
views.py
The view was copied from django-registration and then modified slightly to save the checkbox value onto the user profile. I was able to simplify this function for my usage:
def register(request, backend, form_class=None): """ Copied and modified from registration.views.register """ backend = get_backend(backend) if request.method == 'POST': form = form_class(data=request.POST, files=request.FILES) if form.is_valid(): new_user = backend.register(request, **form.cleaned_data) lProfile = new_user.get_profile() try: request.POST['is_teacher'] lProfile.is_teacher = True lProfile.save() except KeyError: pass to, args, kwargs = backend.post_registration_redirect(request, new_user) return redirect(to, *args, **kwargs) else: form = form_class() context = RequestContext(request) return render_to_response('registration/registration_form.html', { 'form': form }, context_instance=context)
I'm using the technique at http://drumcoder.co.uk/blog/2011/mar/26/auto-creating-django-profiles/ to ensure that the profile is always available.