从空 Django 项目开始,到 MySQL 存储,再到 User + Role 权限控制跑通*
一、创建 Django 项目和 app
1. 创建项目
django-admin startproject DjangoProject_RBAC
cd DjangoProject_RBAC
2. 创建两个 app
python manage.py startapp user
python manage.py startapp role
最终结构大概是:
DjangoProject_RBAC/
├── manage.py
├── DjangoProject_RBAC/
│ ├── settings.py
│ ├── urls.py
│ └── ...
├── user/
│ ├── models.py
│ ├── admin.py
│ ├── views.py
│ ├── urls.py
│ └── ...
└── role/
├── models.py
├── admin.py
└── ...
二、配置 MySQL
1. 安装 pymysql
pip install pymysql
2. 在项目初始化文件中配置 pymysql
打开:
DjangoProject_RBAC/__init__.py
写入:
import pymysql
pymysql.install_as_MySQLdb()
3. 在 MySQL 中创建数据库
进入 MySQL:
mysql -u root -p
创建数据库:
CREATE DATABASE dj_rbac DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
如果你用的是 root 用户,就先这样即可。
三、修改 settings.py
打开:
DjangoProject_RBAC/settings.py
1. 注册 app
找到 INSTALLED_APPS,加入:
"role",
"user",
完整类似这样:
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"role",
"user",
]
2. 配置自定义用户模型
在 settings.py 中加入:
AUTH_USER_MODEL = "user.User"
意思是:
使用 user app 里的 User 模型作为 Django 的用户模型
3. 配置 MySQL 数据库
把原来的 SQLite 配置:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
改成 MySQL:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "dj_rbac",
"USER": "root",
"PASSWORD": "你的MySQL密码",
"HOST": "localhost",
"PORT": "3306",
"OPTIONS": {
"charset": "utf8mb4",
},
}
}
注意:
"USER": "root"
不要写成:
"USER": "roob"
你之前的报错就是这里写错导致的。
四、创建 Role 模型
打开:
role/models.py
写入:
from django.db import models
class Role(models.Model):
ROLE_CHOICES = (
("admin", "管理员"),
("editor", "编辑员"),
("viewer", "查看者"),
)
name = models.CharField(
max_length=50,
choices=ROLE_CHOICES,
unique=True,
verbose_name="角色名称",
)
desc = models.CharField(
max_length=255,
blank=True,
null=True,
verbose_name="角色描述",
)
class Meta:
db_table = "role"
verbose_name = "角色"
verbose_name_plural = "角色"
def __str__(self):
return self.get_name_display()
这个模型会生成一张表:
role
里面保存:
admin 管理员
editor 编辑员
viewer 查看者
五、创建 User 模型
打开:
user/models.py
写入:
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
role = models.ForeignKey(
"role.Role",
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="users",
verbose_name="角色",
)
phone = models.CharField(
max_length=20,
blank=True,
null=True,
verbose_name="手机号",
)
class Meta:
db_table = "user"
verbose_name = "用户"
verbose_name_plural = "用户"
def __str__(self):
return self.username
def is_admin_role(self):
return self.role and self.role.name == "admin"
def is_editor_role(self):
return self.role and self.role.name == "editor"
def is_viewer_role(self):
return self.role and self.role.name == "viewer"
这个模型会生成一张表:
user
并且 user 表里会有一个字段关联 role 表。
关系是:
一个用户 -> 一个角色
例如:
admin 用户 -> 管理员角色
tom 用户 -> 编辑员角色
jack 用户 -> 查看者角色
六、注册后台管理
1. 注册 Role
打开:
role/admin.py
写入:
from django.contrib import admin
from .models import Role
@admin.register(Role)
class RoleAdmin(admin.ModelAdmin):
list_display = ["id", "name", "desc"]
search_fields = ["name"]
2. 注册 User
打开:
user/admin.py
写入:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
@admin.register(User)
class CustomUserAdmin(UserAdmin):
list_display = [
"id",
"username",
"email",
"phone",
"role",
"is_active",
"is_staff",
"is_superuser",
]
list_filter = [
"role",
"is_active",
"is_staff",
"is_superuser",
]
fieldsets = UserAdmin.fieldsets + (
(
"额外信息",
{
"fields": (
"phone",
"role",
)
},
),
)
add_fieldsets = UserAdmin.add_fieldsets + (
(
"额外信息",
{
"fields": (
"phone",
"role",
)
},
),
)
这样后台新增和编辑用户时,都可以看到:
phone
role
七、执行数据库迁移
执行:
python manage.py makemigrations
然后:
python manage.py migrate
成功后,MySQL 中会出现这些表:
auth_group
auth_group_permissions
auth_permission
django_admin_log
django_content_type
django_migrations
django_session
role
user
user_groups
user_user_permissions
其中最重要的是:
role
user
user_groups 和 user_user_permissions 是因为你的 User 继承了 AbstractUser,Django 自动生成的,正常。
八、创建超级管理员
执行:
python manage.py createsuperuser
你已经创建了:
Username: admin
Superuser created successfully.
这一步完成后,user 表里会有一个超级管理员用户。
九、启动项目并进入后台
启动:
python manage.py runserver
浏览器访问:
http://127.0.0.1:8000/admin/
用刚才创建的管理员账号登录。
十、在后台创建角色
进入后台后,找到:
Role / 角色
新增三条角色。
第一条:
name: admin
desc: 管理员
第二条:
name: editor
desc: 编辑员
第三条:
name: viewer
desc: 查看者
你已经创建成功了,后台显示:
管理员 admin
编辑员 editor
查看者 viewer
十一、给 admin 用户分配角色
进入后台:
User / 用户
点开你的 admin 用户。
找到:
角色
选择:
管理员
保存。
这样你的用户关系就是:
admin 用户 -> admin 角色
十二、编写权限判断逻辑
打开:
user/views.py
写入:
from functools import wraps
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
def role_required(role_name):
def decorator(view_func):
@wraps(view_func)
def wrapper(request, *args, **kwargs):
user = request.user
if not user.is_authenticated:
raise PermissionDenied("请先登录")
if not user.role:
raise PermissionDenied("你还没有分配角色")
if user.role.name != role_name:
raise PermissionDenied("你没有权限访问这个页面")
return view_func(request, *args, **kwargs)
return wrapper
return decorator
@login_required
@role_required("admin")
def admin_page(request):
return HttpResponse("这是管理员页面,只有 admin 可以访问")
@login_required
@role_required("editor")
def editor_page(request):
return HttpResponse("这是编辑员页面,只有 editor 可以访问")
@login_required
@role_required("viewer")
def viewer_page(request):
return HttpResponse("这是查看者页面,只有 viewer 可以访问")
这段代码的核心是:
@role_required("admin")
意思是:
只有 role.name 等于 admin 的用户才能访问
十三、创建 user app 的路由
在 user 目录下创建:
user/urls.py
写入:
from django.urls import path
from . import views
urlpatterns = [
path("admin-page/", views.admin_page, name="admin_page"),
path("editor-page/", views.editor_page, name="editor_page"),
path("viewer-page/", views.viewer_page, name="viewer_page"),
]
这三个地址分别是:
/user/admin-page/
/user/editor-page/
/user/viewer-page/
十四、配置项目主路由
打开:
DjangoProject_RBAC/urls.py
写成:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("user/", include("user.urls")),
]
注意这里有两个重点:
from django.urls import path, include
以及:
path("user/", include("user.urls")),
不要写成:
include("user.urls.py")
正确的是:
include("user.urls")
十五、测试权限
重新启动项目:
python manage.py runserver
先登录后台:
http://127.0.0.1:8000/admin/
然后访问:
http://127.0.0.1:8000/user/admin-page/
你已经成功看到:
这是管理员页面,只有 admin 可以访问
说明这条链路已经完全跑通:
浏览器访问 /user/admin-page/
↓
Django 匹配 DjangoProject_RBAC/urls.py
↓
进入 user/urls.py
↓
执行 views.admin_page
↓
login_required 判断是否登录
↓
role_required("admin") 判断角色是否是 admin
↓
当前用户是 admin 角色
↓
允许访问
十六、测试没有权限的页面
继续访问:
http://127.0.0.1:8000/user/editor-page/
因为你当前用户是:
admin 角色
而这个页面要求:
editor 角色
所以应该会出现:
403 Forbidden
这是正确结果。
再访问:
http://127.0.0.1:8000/user/viewer-page/
也应该是 403。
十七、目前完整流程总结
你已经完成了:
1. 创建 Django 项目
2. 创建 user app
3. 创建 role app
4. 配置 MySQL
5. 使用 pymysql 连接 MySQL
6. 自定义 User 模型
7. 创建 Role 模型
8. User 关联 Role
9. 迁移表到 MySQL
10. 创建超级管理员
11. 后台创建角色
12. 后台给用户分配角色
13. 编写角色权限装饰器
14. 配置 user 路由
15. 配置项目主路由
16. 测试 admin 页面成功访问
最终数据库关系是:
role 表
id
name
desc
user 表
id
username
password
email
phone
role_id
关系是:
role.id ← user.role_id
也就是:
一个角色可以对应多个用户
一个用户只能拥有一个角色
十八、你现在项目里的核心文件
最终你需要关注这几个文件:
DjangoProject_RBAC/settings.py
DjangoProject_RBAC/urls.py
role/models.py
role/admin.py
user/models.py
user/admin.py
user/views.py
user/urls.py
十九、完整访问路径
/admin/
后台管理页面。
/user/admin-page/
管理员页面。
/user/editor-page/
编辑员页面。
/user/viewer-page/
查看者页面。
你目前的版本已经是一个完整可运行的 Django + MySQL + User + Role 简单权限控制系统。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)