Search code examples
djangodjango-registration

How to subclass registration form in django-registration


I wish to have the user agree to a TOS and to also support unique emails. django-registration has two different subclassed registration forms that does this: RegistrationFormTermsOfService and RegistrationFormUniqueEmail.

Do I have to make my own sublcass of RegistrationForm and then provide both those features? If so, how would this be accomplished? Would the registration form live inside my app's forms.py or somewhere else?


Solution

  • A quick look at the source for the two classes shows:

    class RegistrationFormTermsOfService(RegistrationForm):
        """
        Subclass of ``RegistrationForm`` which adds a required checkbox
        for agreeing to a site's Terms of Service.
    
        """
        tos = forms.BooleanField(widget=forms.CheckboxInput,
                                 label=_(u'I have read and agree to the Terms of Service'),
                                 error_messages={'required': _("You must agree to the terms to register")})
    
    
    class RegistrationFormUniqueEmail(RegistrationForm):
        """
        Subclass of ``RegistrationForm`` which enforces uniqueness of
        email addresses.
    
        """
        def clean_email(self):
            """
            Validate that the supplied email address is unique for the
            site.
    
            """
            if User.objects.filter(email__iexact=self.cleaned_data['email']):
                raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
            return self.cleaned_data['email']
    

    As you can see these two classes don't overwrite methods defined by the other so you should be able to just define your own class as being:

    from registration.forms import RegistrationFormUniqueEmail, RegistrationFormTermsOfService
    class RegistrationFormTOSAndEmail(RegistrationFormUniqueEmail, RegistrationFormTermsOfService):
        pass
    

    And it should function, however I have not tested this. As to where to place this class; forms.py is a good location.

    Update:

    A little reading at https://django-registration.readthedocs.org/en/latest/views.html which tells us that we can pass the view some parameters via the url definition; for instance a form class. Simply use a URL like:

    url(r'^register/$',
        RegistrationView.as_view(form_class=RegistrationFormTOSAndEmail), 
        name='registration_register')