【案例】权限管理

发布于:2024-12-06 ⋅ 阅读:(14) ⋅ 点赞:(0)

数据库表结构
models.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

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

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

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

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

<!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

{% 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

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

网站公告

今日签到

点亮在社区的每一天
去签到