What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Django’s built-in authorization connects users and groups to permissions, with content types identifying the models those permissions apply to. Users can receive permissions directly or through groups, but the default ModelBackend grants model-level permissions only—it does not automatically protect individual database objects.
Which Django models make up the authorization system?
The core concepts are User, Group, Permission, and ContentType. Think of them as a set of relationships rather than a universal diagram of physical SQL tables: the actual table and join-table names depend on the Django version, user model, migrations, and database in a particular project.
As an Amazon Associate I earn from qualifying purchases.
- User: The account whose access is being checked. A project can use Django’s default user model or a custom user model.
- Group: A reusable collection of users. Permissions assigned to a group are available to its members.
- Permission: An authorization entry with a human-readable name, a codename used in checks, and a foreign key to a content type.
- ContentType: The record that associates a permission with a model, including its app and model identity.
The auth and contenttypes migrations create the database structures needed for these relationships. To inspect physical table names, check the migrations and schema for the project’s installed Django version and configured user model rather than assuming every deployment has identical names.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →How does Django name and check a permission?
A permission’s name is its readable label; its codename is the token used by authorization checks. The usual permission string combines the app label and codename, separated by a period. For example, blog.change_post refers to the change_post permission for the relevant model in the blog app.
#1 Best Overall
With django.contrib.auth installed, Django creates the standard add, change, delete, and view permissions for each model in installed applications. These permissions are created through migrations. A check typically looks like:
user.has_perm("blog.change_post")
Custom permissions can be declared in a model’s metadata or created and assigned explicitly. Proxy models have their own content type when configured accordingly; they do not automatically inherit the concrete model’s permissions.
Rank #2
How do users get permissions?
There are two built-in assignment paths. A user can receive a permission directly through user_permissions, or receive it through a group they belong to. Users can belong to multiple groups, and permissions from those groups are available to them.
Recommended Free Tools
| Assignment path | Best fit | How a change propagates | Maintenance trade-off |
|---|---|---|---|
| Direct user permission | An individual exception or one-off grant | Applies to that user | Can become difficult to manage when many users need the same access |
| Group permission | A reusable role or access bundle | Applies to members of the group | Central group changes are easier to maintain, but membership and group definitions must be kept accurate |
For the default database-backed permission mechanism, the permissions assigned directly to a user and those available through their groups contribute to the user’s model-level permissions. A project may also configure authentication backends that supply additional permissions, so database assignments alone may not describe every effective permission.
What does the default permission backend enforce?
Django delegates permission lookup to configured authentication backends. The default ModelBackend handles model-level permissions; it does not implement per-object permissions. Passing an object to its permission checks does not make the permission object-specific: this backend returns no permissions for that object.
That distinction matters when access depends on a particular row—for example, allowing a user to edit one post but not every post. The built-in model permission answers whether the user has a permission for the model, not whether that user may act on a particular instance. Projects that need row-level authorization must add an object-aware backend or another authorization implementation, then apply its checks in the application.
Custom backends can contribute permissions. Django treats a permission granted by any backend as granted, unless a backend raises PermissionDenied, which stops further checking. Consequently, inspecting auth tables alone may not reveal all permissions effective in a project with customized backends.
Why might a permission change not show up immediately?
The default backend caches permission results on a user instance after lookup. If code changes permissions and then checks them again using that same instance, the result may reflect the cached permissions rather than the latest database state. Fetch the user again from the database before checking. Calling refresh_from_db() does not clear this permission cache.
Quick Recap
Best Value
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




