[Fixed]-Making first name, last name a required attribute rather than an optional one in Django's auth User model


I would definitely go with validating on the form. You could even go as far as having more form validation in the admin if you felt like it.



Simplest solution

  • Just create a custom UserRegisterForm which inherits the django’s default UserCreationForm.
  • The first_name and last_name are already attributes of django’s default User. If you want to make them as required fields, then recreate those fields as forms.CharField(...).

Now use your own User register form.

# Contents usersapp/forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm

# Inherit Django's default UserCreationForm
class UserRegisterForm(UserCreationForm):
    first_name = forms.CharField(max_length=50) # Required
    last_name = forms.CharField(max_length=50) # Required
    # All fields you re-define here will become required fields in the form

    class Meta:
        model = User
        fields = ['username', 'email', 'first_name', 'last_name', 'password1', 'password2']


Thanks Mbuso for the advice. Here’s my full implementation for those who are interested. Before taking a look at the source, let’s see what it looks like:
Admin Web Screenshot

I’ve implemented a profile model, but this will work just fine without it.

from django.core.exceptions import ValidationError
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm
from django.contrib.auth.models import User
from apps.profiles.models import Profile

# Define an inline admin descriptor for Profile model
# which acts a bit like a singleton
class UserProfileInline(admin.StackedInline):
    model = Profile
    can_delete = False
    verbose_name_plural = 'profile'

class MyUserChangeForm(UserChangeForm):
    def clean_first_name(self):
        if self.cleaned_data["first_name"].strip() == '':
            raise ValidationError("First name is required.")
        return self.cleaned_data["first_name"]

    def clean_last_name(self):
        if self.cleaned_data["last_name"].strip() == '':
            raise ValidationError("Last name is required.")
        return self.cleaned_data["last_name"]

# Define a new User admin
class MyUserAdmin(UserAdmin):
    form = MyUserChangeForm
    inlines = UserProfileInline,

admin.site.register(User, MyUserAdmin)

Note: If you do implement a profile model, recommend using UserProfile as the name, since is this is what’s in the documentation and seems to be the standard (this part was developed before I started working on the project). If you’re using Django 1.5 or higher, skip UserProfile all together and extend the User model.


The Django way of extending the basic User model is through user profiles: see “Storing additional information about users“.

If it does not fit your needs, django.contrib.auth is just a Django application, I would simply fork it. As long as you abide by the original interface, I think you will be out of trouble.

Another option is Pinax – it has OpenId support built in, you can use it with your own openid provider. OpenId native support is a battery I really miss in Django.

Leave a comment