【案例】权限管理

数据库表结构

models.py

py 复制代码
from django.db import models


class Permission(models.Model):
    """ 权限表 """
    code = models.CharField(verbose_name="路由名称", max_length=32)
    name = models.CharField(verbose_name="名称", max_length=32)


class Role(models.Model):
    """ 角色表 """
    name = models.CharField(verbose_name="名称", max_length=32)

    permissions = models.ManyToManyField(verbose_name="权限", to="Permission")


class User(models.Model):
    """ 用户表 """
    username = models.CharField(verbose_name="用户名", max_length=32)
    password = models.CharField(verbose_name="密码", max_length=32)
    is_super = models.BooleanField(verbose_name="是否管理员", default=False)

    roles = models.ManyToManyField(verbose_name="权限", to="Role")


class Computer(models.Model):
    """ 电脑 """
    title = models.CharField(verbose_name="名称", max_length=32)
    price = models.IntegerField(verbose_name="价格")


class Order(models.Model):
    """ 订单 """
    title = models.CharField(verbose_name="订单", max_length=32)
    price = models.IntegerField(verbose_name="价格")

使用命令行创建超级用户

management/commands/superuser.py

py 复制代码
from django.core.management.base import BaseCommand
from www import models


class Command(BaseCommand):
    def handle(self, *args, **options):
        username = input("请输入用户名:")
        password = input("请输入密码:")

        models.User.objects.create(username=username, password=password, is_super=True)

使用离线脚本创建角色和用户

scripts/创建普通用户及权限.py

py 复制代码
import django
import os
import sys

base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'rbac.settings')
django.setup()

from www import models
#
# models.Permission.objects.bulk_create([
#     models.Permission(code="computer", name="电脑管理"),
#     models.Permission(code="computer_add", name="电脑添加"),
#     models.Permission(code="computer_edit", name="电脑编辑"),
#     models.Permission(code="computer_del", name="电脑删除"),
# ])
#
# role = models.Role.objects.create(name="运营实习生")
# role.permissions.set([1, 2])
#
# role = models.Role.objects.create(name="正式员工")
# role.permissions.set([1, 2, 3, 4])
#
# user = models.User.objects.create(username="cqn", password="123", is_super=False)
# user.roles.set([1])
#
# user = models.User.objects.create(username="zkf", password="123", is_super=False)
# user.roles.set([1, 2])

views.py

py 复制代码
from django.shortcuts import render, HttpResponse, redirect
from django.forms import ModelForm
from django.forms.models import model_to_dict
from www import models


class LoginModelForm(ModelForm):
    class Meta:
        model = models.User
        fields = ["username", "password"]


def login(request):
    if request.method == "GET":
        form = LoginModelForm()
        return render(request, "login.html", {"form": form})

    form = LoginModelForm(data=request.POST)
    if not form.is_valid():
        return render(request, "login.html", {"form": form})

    user_object = models.User.objects.filter(**form.cleaned_data).first()
    if not user_object:
        form.add_error("password", "用户名或密码错误")
        return render(request, "login.html", {"form": form})

    # request.session["user_session_key"] = {
    #     "id": user_object.id,
    #     "username": user_object.username,
    #     "is_super": user_object.is_super
    # }
    request.session["user_session_key"] = model_to_dict(user_object, fields=["id", "username", "is_super"])
    return redirect("home")


def home(request):
    return HttpResponse("HOME")


def computer(request):
    return render(request, 'computer.html')


def computer_add(request):
    return HttpResponse("OK")


def computer_edit(request, id):
    return HttpResponse("OK")


def computer_del(request, id):
    return HttpResponse("OK")


def order(request):
    return HttpResponse("OK")


def order_add(request):
    return HttpResponse("OK")


def order_edit(request, id):
    return HttpResponse("OK")


def order_del(request, id):
    return HttpResponse("OK")

中间件

utils/md.py

py 复制代码
from django.contrib.auth.middleware import MiddlewareMixin
from django.urls import reverse
from django.shortcuts import redirect, HttpResponse
from www import models


class AuthMiddleware(MiddlewareMixin):
    def process_request(self, request):
        if request.path_info in [reverse("login")]:
            return

        user_dict = request.session.get("user_session_key")
        if not user_dict:
            return redirect("login")

        request.user_dict = user_dict


class PermissionMiddleware(MiddlewareMixin):
    def process_view(self, request, callback, *args, **kwargs):
        if request.path_info in [reverse("login")]:
            return

        if request.user_dict["is_super"]:
            return

        # 用户访问的rl
        url_name = request.resolver_match.url_name
        print("PermissionMiddleware中间件: ", url_name)

        # 用户对象
        user_object = models.User.objects.filter(id=request.user_dict['id']).first()

        # 用户所有的角色,角色对应的权限
        user_per_list = user_object.roles.all().values("permissions__code", "permissions__name")
        permission_dict = {item["permissions__code"]: item["permissions__name"] for item in user_per_list}
        print("PermissionMiddleware中间件: ", permission_dict)

        request.permission_dict = permission_dict

        if url_name in permission_dict:
            return

        return HttpResponse("无权访问")

前端页面

templates/login.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>用户登录</h2>
<form method="post" novalidate>
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">登录</button>
</form>

</body>
</html>

templates/computer.html

html 复制代码
{% load permission %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% if request|has_permission:"computer_add" %}
    <a href="{% url "computer_add" %}">新增</a>
{% endif %}

{% if request|has_permission:"computer_edit" %}
    <a href="{% url "computer_edit" id=1 %}">编辑</a>
{% endif %}

{% if request|has_permission:"computer_del" %}
    <a href="{% url "computer_del" id=1 %}">删除</a>
{% endif %}

</body>
</html>

templatetags/permission.py

py 复制代码
from django.template import Library

register = Library()


@register.filter
def has_permission(request, route_name):
    is_super = request.user_dict['is_super']
    if is_super:
        return True

    if route_name in request.permission_dict:
        return True

    return False
相关推荐
jnrjian9 小时前
text index 查看index column index定义 index 刷新频率 index视图
数据库·oracle
瀚高PG实验室10 小时前
审计策略修改
网络·数据库·瀚高数据库
言慢行善10 小时前
sqlserver模糊查询问题
java·数据库·sqlserver
韶博雅10 小时前
emcc24ai
开发语言·数据库·python
有想法的py工程师10 小时前
PostgreSQL 分区表排序优化:Append Sort 优化为 Merge Append
大数据·数据库·postgresql
迷枫71211 小时前
达梦数据库的体系架构
数据库·oracle·架构
夜晚打字声11 小时前
9(九)Jmeter如何连接数据库
数据库·jmeter·oracle
Chasing__Dreams11 小时前
Mysql--基础知识点--95--为什么避免使用长事务
数据库·mysql
NineData12 小时前
NineData 智能数据管理平台新功能发布|2026 年 3 月
数据库·oracle·架构·dba·ninedata·数据复制·数据迁移工具
小陈工12 小时前
2026年4月7日技术资讯洞察:下一代数据库融合、AI基础设施竞赛与异步编程实战
开发语言·前端·数据库·人工智能·python