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