What's in a name? That's up to you

The abstract models for users in Django allows many applications to define a custom User model easily. There is an aspect which is problematic for a general-purpose framework: names of people.

The default assumption: first_name and last_name

On the AbstractUser model – and therefore by default on any subclass, such as the normal User model – the first_name and last_name fields are currently limited to 30 characters each. This is a compromise to allow some expected use cases: addressing a person by their given name (first_name), sorting the name by surname (last_name), and storing those as separate fields that fit into templates.

>>> import django.contrib.auth
>>> user = django.contrib.auth.models.User(
...     first_name="Lindsay", last_name="Scott")

That limit of 30 characters gets a little cramped, though. There are cultures in the world where the value that goes into that field can get quite long:

>>> user = django.contrib.auth.models.User(
...     first_name="Edward", last_name="Wong Hau Pepelu Tivrusky IV")

In Django 2, the last_name field limit is increased to 150 characters:

>>> user = django.contrib.auth.models.User(
...     first_name="Hubert",
...     last_name="Vernon Rudolph Clayton Irving Wilson Alva Anton Jeff Harley Timothy Curtis Cleveland Cecil Ollie Edmund Eli Wiley Marvin Ellis Espinoza")

The work-around: get_short_name and get_full_name

To get the name as a single value, the model has a pair of methods, get_short_name and get_full_name:

>>> user.get_short_name()

>>> user.get_full_name()
'Lindsay Scott'

These methods are, in Django 1, defined in the AbstractBaseUser class. They are used in various places in standard and third-party Django libraries, so they are the ones to override if you want some other behaviour for “short name” and “full name”.

Less hung up on user names

You can implement a custom User model that does not have first_name and last_name:

>>> from django.db import models
>>> class User(django.contrib.auth.models.AbstractBaseUser):
...     class Meta:
...         app_label = 'lorem'
...     name = models.CharField(max_length=200)

In Django 1, the class is not complete because it does not implement the get_short_name and get_full_name methods:

>>> user = User(name="Edward Wong Hau Pepelu Tivrusky IV")
>>> user.get_short_name()
NotImplementedError: subclasses of AbstractBaseUser must provide a get_short_name() method.

This error happens when, for example, the Django Admin site needs to display a User record. Your admin will crash just because you didn't define those methods.

But perhaps we only ever want to use User in ways that use only one of those methods, or neither. Django 2 removes that restriction on User classes. The Admin will now use the get_short_name and get_full_name methods only if your User model defines them.

Do you have questions about Django, or want to hire me for some work in a Django-related project? Come chat to me either privately at my Matrix address @bignose:matrix.org, or in the public Django chat channel.