Skip to content

Logging In & Registering Models

The admin was added to our project when we first generated it.

  • django.contrib.admin is added to INSTALLED_APPS by default
  • startproject added the admin/ URL pattern to config/urls.py.

Create a Superuser

A superuser is an account with full privileges in the admin. We'll use one as the admin account, to set the site up. Quit the shell with exit() if it's open, and create one:

shell
uv run manage.py createsuperuser

Django asks for a username, an email address, and a password. We'll use:

  • Username: admin
  • Email address: leave it empty
  • Password: rescue-admin

createsuperuser saves the account as a row of our custom user model, accounts.User, with the password hashed.

Log In

runserver is Django's web server for development, not for production. Start the server in a second terminal with uv run manage.py runserver, and leave it running. The dev server restarts when a Python file changes.

Open http://127.0.0.1:8000/admin/ and log in as admin / rescue-admin.

The admin lists Groups, a built-in model. Our models aren't registered yet.

Warning

Only the people who run the site should have admin accounts.

Register the Animal Model

The admin only shows the models that are registered. Open animals/admin.py and replace it with:

Python
from django.contrib import admin

from .models import Animal


@admin.register(Animal)
class AnimalAdmin(admin.ModelAdmin):
    pass

A ModelAdmin class holds the admin's settings for one model, and ours has none yet. The @admin.register(Animal) decorator registers AnimalAdmin as the admin for Animal.

Register the User Model

Open accounts/admin.py and replace it with:

accounts/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .models import User

admin.site.register(User, UserAdmin)

Our User has the built-in user's fields, so the built-in UserAdmin fits it.

The List Page

Reload the admin.

There are two new sections:

  • Accounts with Users
  • Animals, with a link to our model.

Click Animals to see the list page.

Each row shows the animal's name, from the model's __str__.

The Change Form

Click Pepper to open the form for one animal. Django chose an input for each field based on its type:

  • name and breed are text inputs
  • species and status are dropdowns, built from their choices
  • birth_date and intake_date have a date picker
  • photo is a file input. Its Currently: link opens the photo, from /media/animals/.

Now clear the Name field and click Save.

The form comes back with an error: "This field is required."

Why was the blank name refused?

The admin checks each field's rules from the model, such as blank and max_length, before it saves anything.