【案例】权限管理

数据库表结构

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
相关推荐
forestsea3 分钟前
MySQL 入门大全:数据类型
数据库·mysql
为自己_带盐31 分钟前
浅聊一下数据库的索引优化
开发语言·数据库·php
gb42152871 小时前
mysql数据库中某个数据表的碎片率自己降低了,mysql数据表对碎片率有自动优化机制吗?
数据库·mysql
AI大模型顾潇1 小时前
[特殊字符] 本地大模型编程实战(29):用大语言模型LLM查询图数据库NEO4J(2)
前端·数据库·人工智能·语言模型·自然语言处理·prompt·neo4j
有时间要学习1 小时前
MySQL——数据类型&&表的约束
数据库·mysql
AI改变未来2 小时前
数据库常见故障排查
数据库
bing_1582 小时前
MongoDB 的核心概念(文档、集合、数据库、BSON)是什么?
数据库·mongodb·oracle
feilieren2 小时前
Windows 安装 Milvus
数据库·ai·milvus
kngines2 小时前
【PostgreSQL数据分析实战:从数据清洗到可视化全流程】附录-D. 扩展插件列表(PostGIS/PostgREST等)
数据库·postgresql·数据分析·pgvector·扩展插件·postgrest·向量数据
星星点点洲2 小时前
【Redis】谈谈Redis的设计
数据库·redis·缓存