The short version
Django creates 5 core auth tables: auth_user, auth_group, auth_permission, django_content_type, and two join tables (auth_user_groups, auth_group_permissions). The permission system is built on content types -- each model gets a default add, change, delete, and view permission.
The core tables
auth_user
| Column | Type | What it means |
|---|---|---|
id | int (PK) | Auto-incrementing primary key. |
password | varchar(128) | Hashed password (PBKDF2 by default). |
last_login | datetime | When the user last logged in. |
is_superuser | bool | Bypasses all permission checks. |
username | varchar(150) | Unique username. |
email | varchar(254) | Email address. |
is_staff | bool | Can access the Django admin. |
is_active | bool | Set to False instead of deleting users. |
auth_group
| Column | Type | What it means |
|---|---|---|
id | int (PK) | Auto-incrementing ID. |
name | varchar(150) | Unique group name (e.g., "Editors"). |
auth_permission
| Column | Type | What it means |
|---|---|---|
id | int (PK) | Auto-incrementing ID. |
name | varchar(255) | Human-readable name (e.g., "Can add post"). |
content_type_id | int (FK) | Which model this permission applies to. |
codename | varchar(100) | Code identifier (e.g., add_post). |
django_content_type
Maps every model in your project to an ID. The permission system uses it to know which model a permission applies to.
How permissions work
A permission is tied to a content type (a model). Groups collect permissions. Users are added to groups to inherit their permissions. You can also assign permissions directly to users.
FAQ
Does Django create all these tables automatically?
Yes. Running python manage.py migrate creates all auth tables.
What's the difference between is_superuser and is_staff?is_superuser bypasses all permission checks. is_staff only controls access to the Django admin.
Can I use Django without the permission system?
Yes. Remove django.contrib.auth from INSTALLED_APPS.