权限分配之角色管理

"""
权限分配
    a. 角色管理
        
    b. 用户管理
        
    c. 菜单和权限管理
        
    d. 批量的权限操作
        
    e. 分配权限
"""

角色管理示例图:

权限分配之角色管理

 

 权限分配之角色管理

 

 权限分配之角色管理

 

 权限分配之角色管理

第一步:总路由进行分发

Example/urls.py

from django.contrib import admin
from django.urls import path, include, re_path

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r"^rbac/", include(("rbac.urls", "rbac"))),
    re_path(r"^", include("app01.urls")),
]

第二步:之前对权限进行了判断,所以先把权限判断的代码注释掉,方便后续的代码书写

1. 中间件的注释(Example/settings.py)
# 'rbac.middlewares.rbac.RbacMiddleware',

2. 模板中的注释(app01/templates/layout.html)
{#{% menu request %}#}
{#{% url_record request %}#}

第三步:路由的创建

rbac/urls.py

from django.urls import re_path
from rbac.views import role

urlpatterns = [
    re_path(r'^role/list/$', role.role_list, name="role_list"),
    re_path(r'^role/add/$', role.role_add, name="role_add"),
    re_path(r'^role/edit/(?P<pk>\d+)$', role.role_edit, name="role_edit"),
    re_path(r'^role/del/(?P<pk>\d+)$', role.role_del, name="role_del"),
]

第四步:ModelForm的创建

rbac/forms/role.py

from django import forms
from rbac import models


class RoleModelForm(forms.ModelForm):
    class Meta:
        model = models.Role  # 关联的表
        fields = ["title",]  # 字段
        widgets = {
            "title": forms.TextInput(attrs={"class": "form-control"})  # 添加bootstrap样式
        }

第五步:视图的创建

rbac/views/role.py

"""角色管理"""
from rbac import models
from django.shortcuts import render, redirect, HttpResponse
from django.urls import reverse
from rbac.forms.role import RoleModelForm


def role_list(request):
    """
    角色列表
    :param request:
    :return:
    """
    role_queryset = models.Role.objects.all().order_by("pk")
    return render(request, "rbac/role_list.html", {"roles": role_queryset})


def role_add(request):
    """
    添加角色
    :param request:
    :return:
    """
    if request.method == "GET":
        form = RoleModelForm()
        return render(request, "rbac/change.html", {"form": form})
    form = RoleModelForm(data=request.POST)  # 保存
    if form.is_valid():
        form.save()
        return redirect(reverse("rbac:role_list"))
    return render(request, "rbac/change.html", {"form": form})


def role_edit(request, pk):
    """
    角色编辑
    :param request:
    :param pk: 要修改的角色ID
    :return:
    """
    obj = models.Role.objects.filter(id=pk).first()
    if not obj:
        return HttpResponse("角色不存在...")
    if request.method == "GET":
        form = RoleModelForm(instance=obj)  # 将原有的数据展示
        return render(request, "rbac/change.html", {"form": form})
    form = RoleModelForm(instance=obj, data=request.POST)  # 保存编辑后的数据
    if form.is_valid():
        form.save()
        return redirect(reverse("rbac:role_list"))
    return render(request, "rbac/change.html", {"form": form})


def role_del(request, pk):
    """
    删除角色
    :param request:
    :param pk:
    :return:
    """
    origin_url = reverse("rbac:role_list")
    if request.method == "GET":
        return render(request, "rbac/delete.html", {"cancel_url": origin_url})
    models.Role.objects.filter(id=pk).delete()
    return redirect(origin_url)

"""
1. 添加和编辑页面基本一样,所以再添加和编辑的视图函数中,返回相同的html
2. 删除功能都可以用到二次确认的操作,所以delete.html也可以共用,取消则代表返回的上一级页面,上一级页面的url
由后端传递给前端即可,而确认的url是根据form表单,而form表单没有填写url,则代表提交数据的url是浏览器窗口当前
的url
"""

第六步:模板的创建

rbac/templates/rbac/role_list.html

{% extends 'layout.html' %}

{% block content %}
    <div class="luffy-container">
        <div class="btn-group" style="margin: 5px 0">
            <a class="btn btn-default" href="{% url 'rbac:role_add' %}">
                <i class="fa fa-plus-square" aria-hidden="true"></i> 添加角色
            </a>
        </div>
        <table class="table table-bordered table-hover">
            <thead>
            <tr>
                <th>ID</th>
                <th>名称</th>
                <th>选项</th>
            </tr>
            </thead>
            <tbody>
            {% for row in roles %}
                <tr>
                    <td>{{ row.id }}</td>
                    <td>{{ row.title }}</td>
                    <td>
                        <a style="color: #333333;" href="{% url 'rbac:role_edit' pk=row.id %}">
                            <i class="fa fa-edit" aria-hidden="true"></i></a>
                        <a style="color: #d9534f;" href="{% url 'rbac:role_del' pk=row.id %}"><i class="fa fa-trash-o"></i></a>
                    </td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
    </div>
{% endblock %}

rbac/templates/rbac/change.html

{% extends 'layout.html' %}

{% block content %}
    <div class="luffy-container">
        <form class="form-horizontal" method="post" novalidate>
            {% csrf_token %}
            {% for foo in form %}
                <div class="form-group">
                    <label class="col-sm-2 control-label">{{ foo.label }}</label>
                    <div class="col-sm-8">
                        {{ foo }}
                        <span style="color: red">{{ foo.errors.0 }}</span>
                    </div>
                </div>
            {% endfor %}
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-8">
                    <input type="submit" value="保存" class="btn btn-primary">
                </div>
            </div>
        </form>
    </div>
{% endblock %}

rbac/templates/rbac/delete.html

{% extends 'layout.html' %}

{% block content %}
    <div class="luffy-container">
        <div class="alert alert-danger" role="alert">
            <form method="post">
                {% csrf_token %}
                <p style="font-size: 13px;">
                    <i class="fa fa-warning" aria-hidden="true"></i>
                    删除后将不可恢复,请确定是否删除
                </p>
                <div style="margin-top: 20px;">
                    <a href="{{ cancel_url }}" class="btn btn-default btn-sm">取消</a>
                    <input type="submit" class="btn btn-danger btn-sm" value="确认">
                </div>
            </form>
        </div>
    </div>
{% endblock %}

权限分配之角色管理

知识点:

  - ModelForm
  - 根据namespace和name反向生成URL
  - 模板的查找顺序(先从根目录的templates查找,然后根据所注册的app顺序进行查找,所以为了避开重名,在app的templates目录中再创建一个目录)

上一篇:Gavin老师Transformer直播课感悟 - 基于Transformer的Rasa 3.x 内核解密之透视Rasa Form的NLU及Policies的内部工作机制案例实战(三十九)


下一篇:ElementUI和Ant Design对比