4

I'm using the Django-Registration package to have users create accounts, authenticate them and log in to my webapp.

However, the form/view for account creation doesn't ask the user for a firstname/last name (those fields are part of the model BTW). It only asks for their email address, login ID and password (twice). I would like it to ask for the user's first name/last name (these fields can be optional... but it should still ask). I cannot find the form and view files to modify such that it asks for this info. I have modified the template file. But without the form and view modifications that's useless. How is this done?

Saqib Ali
  • 11,931
  • 41
  • 133
  • 272

3 Answers3

6

In your forms.py, extend the DjangoRegistration form like:

class MyExtendedForm(RegistrationForm):
    first_name = forms.CharField(widget=forms.TextInput(label="first_name"))
    last_name = forms.CharField(widget=forms.TextInput(label="last_name"))

In the urls.py, tell django-registration to use this extended form:

# using my registration form to override the default
(r'^register/$', 
    register, 
    {'backend': 'registration.backends.default.DefaultBackend',
     'form_class': MyExtendedForm}),

Define user_created to save the extra information:

def user_created(sender, user, request, **kwargs):
    """
    Called via signals when user registers. Creates different profiles and
    associations
    """
    form = MyExtendedForm(request.Post)
    # Update first and last name for user
    user.first_name=form.data['first_name']
    user.last_name=form.data['last_name']
    user.save()

Then, register for signals from django-registration to call your function after any registration is processed:

from registration.signals import user_registered
user_registered.connect(user_created)
AlastairC
  • 3,277
  • 21
  • 15
zaphod
  • 2,045
  • 1
  • 14
  • 18
  • After making some relatively minor edits to your code above, this worked. Thanks! – Saqib Ali Apr 03 '13 at 07:20
  • My edits still haven't posted. And your code won't work without them. So for the benefit of others, I'm posting them here: There is a missing closing parenthesis on each of the two lines in class MyExtendedForm. Also the first line in user_created should be form = MyExtendedForm(request.Post). And the definition of user_created must occur before you register it for the signal from Django-registration. – Saqib Ali Apr 03 '13 at 15:45
  • Yes, I had just given a prototype code in logical order. Glad it worked for you. – zaphod Apr 03 '13 at 18:05
  • 1
    Ran into a "cannot import name register" error using django-registration 0.8. [I've posted a fix](http://stackoverflow.com/a/16366997/720054). – Brian May 03 '13 at 20:27
  • There is a typo.It should be `request.POST` (all uppercase) – samir105 Jul 01 '17 at 11:25
2

Once you have everything set up like shown here use following CustomUserForm:

class CustomUserForm(RegistrationForm):
    class Meta(RegistrationForm.Meta):
        model = CustomUser
        fields = ['first_name','last_name','username','email','password1','password2']
Aseem
  • 5,848
  • 7
  • 45
  • 69
0

To add the fields first_name and last_name from the default Django User model provide your own formclass:

Prepend the two fields to Meta.fields of the default RegistrationForm:

from django_registration.forms import RegistrationForm

class RegistrationWithNameForm(RegistrationForm):
    class Meta(RegistrationForm.Meta):
        fields = ["first_name", "last_name"] + RegistrationForm.Meta.fields

Override the default RegistrationView by adding a path to urls.py:

from django_registration.backends.activation.views import RegistrationView
from yourapp.forms import RegistrationWithNameForm

path('accounts/register/',
  RegistrationView.as_view(form_class=RegistrationWithNameForm),
  name='django_registration_register',
),
path("accounts/", include("django_registration.backends.activation.urls")),

Testcase:

from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse

class RegistrationTestCase(TestCase):
    registration_url = reverse("django_registration_register")
    test_username = "testuser"
    post_data = {
        "first_name": "TestFirstName",
        "last_name": "TestLastName",
        "username": test_username,
        "email": "testuser@example.com",
        "password1": "mypass",
        "password2": "mypass"
    }

    def test_register(self):
        response = self.client.post(self.registration_url, self.post_data)
        self.assertRedirects(response, reverse("django_registration_complete"))
        user = get_user_model().objects.get(username=self.test_username)
        # Assert all fields are present on the newly registered user
        for field in ["username", "first_name", "last_name", "email"]:
            self.assertEqual(self.post_data[field], getattr(user, field))