Saqib Ali
Saqib Ali

Reputation: 12645

Django-registration: How to make account creation ask for first/last name

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?

Upvotes: 4

Views: 3453

Answers (3)

Peter Jochum
Peter Jochum

Reputation: 1

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": "[email protected]",
        "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))

Upvotes: 0

Aseem
Aseem

Reputation: 6787

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']

Upvotes: 2

zaphod
zaphod

Reputation: 2105

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)

Upvotes: 6

Related Questions