Skip to main
Name tags

Three Names to Include in Your User Model

(None of them is the username)

The term “username” is ambiguous. When designing a user model there are several kinds of names that are useful to include.

It’s time to start a new project. You want users, so the first thing you do is add a user model with username and password fields and – whoa, hold up.

What’s that username again? Is it the user’s email address? Is it an arbitrary nickname that the user can choose? Is it an automatically generated identifier that should never change?

It’s not for nothing that they say naming things is one of the hard problems in computer science. For modeling user accounts there are three different name fields that you probably want, and for the sake of avoiding confusion let’s not call any of them the username:

  1. The user id. This is the permanent, unchanging identifier of a particular user. It may be generated randomly or it may be an incrementing number, but the important thing is that it should not have any inherent meaning, and it should never change. That makes it safe for use internally throughout the system as a foreign key to refer to the user.
  2. The display name or screen name. This is what will actually be shown when referring to the user in the UI and notifications (to the user themself or to other users). This should be chosen by the user with few limitations (except perhaps on length or to avoid excessive whitespace). That gives users full flexibility to use their offline name (including in other writing systems), nickname, stage name, or even emoji. If it will be shown to multiple users, consider making it be unique to avoid confusion. It should be editable.
  3. The login. This is what the user will type to log in to the system (or what their password manager will type for them). You may be tempted to let users choose their own login, but we prefer to use their email address because it makes it less likely that the user will forget their login. Whatever it is, it must be unique among all the users, and should be editable. If it’s the email address, changing it should require responding to a verification email to verify control of the email account. (Some systems may want to allow a user to set up multiple logins including various email addresses, phone numbers, or social accounts.)

You probably noticed I did not include the user’s given and family names (and middle name and maiden name and…). Avoid collecting these as separate fields unless you need to, i.e. for official or legal purposes. Keep in mind that the preferred order of these names varies in different cultures (so avoid calling them “first name” and “last name”). And keep in mind that they may change over time. Names are hard.

We like Django for building backends. There are a number of ways to extend Django’s default user model. Here’s our custom User model that meets the above guidelines:

from django.db import models
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.base_user import AbstractBaseUser

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField("email address", unique=True)
    name = models.CharField("name", max_length=30, blank=True, unique=True)
    date_joined = models.DateTimeField(_("date joined"), auto_now_add=True)
    is_active = models.BooleanField(_("active"), default=True)

    objects = UserManager()

    USERNAME_FIELD = "email"

    def get_full_name(self):

    def get_short_name(self):

Like all Django models, it has a default id field which meets our criteria for user id. There is a single name field which is used when Django needs to display the user’s name via the get_full_name and get_short_name methods. And it has an email field which enforces uniqueness and is configured as Django’s USERNAME_FIELD (which is really the login).

(Note: This model requires a custom UserManager – I won’t include that here; see Vitor Freitas’ helpful How to Extend the Django User Model article for details.)

Add this model to a new Django project (it’ll be easiest if you use it from the start), configure it using the AUTH_USER_MODEL setting, and you’ll be well on your way to never having to say the word “username” again.

Did we miss anything important? Let us know via Twitter!

Recent Articles

  1. A stand of smartphones
    Article post type

    When to Choose a Native Mobile App

    Part 2 – Responsive Web App vs Native Mobile App vs Progressive Web App

    If you have an idea for a digital product, you may be wondering if you should build a responsive web app, a native mobile app, or a progressive web app. Is one option inherently better? What are the pros and cons? This is part 2 of a three-part series unpacking…

    see all Article posts
  2. spider web with dew drops
    Article post type

    When to Choose a Responsive Web App

    Part 1 – Responsive Web App vs Native Mobile App vs Progressive Web App

    The decision of what platform to use to build your app is quite important – affecting project scope, timeline, and budget. But understanding the differences between a responsive web app, a native mobile app, and a progressive web app – and deciding which one is right for your project …

    see all Article posts
  3. The top front of a bright yellow shipping container with the door open and a blue sky behind it
    Article post type

    Can We Query the Root Container?

    The complexities of containment, overflow, and ‘propagation’

    I spoke about Container Queries at both Smashing Conference (San Francisco) and CSS Day (Amsterdam) – where I recommended setting up a root container to replace most media queries. Since then, Temani Afif pointed out a few issues with that approach, and sent me down a rabbit hole of overlapping…

    see all Article posts