• rbac集成 权限分配。之角色管理


    权限分配功能拆分:
      a. 角色管理
      b. 用户管理
      c. 菜单和权限的管理

      d. 批量的权限操作
      e. 分配权限

    先实现 角色管理: 无非也就是,增删改查:
      定义路由, 编写视图。

    1.查看角色页面:role_list.html

    主路由分发器,先进行分发。  就以 rbac 为开头的作为我们的,后台权限 分配页面的路由起始:

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

     rbac 组件, 再进行路由分发:

    urlpatterns = [
        re_path(r"^role/list/$", role.role_list, name="role_list"),
    ]
    

     为了 避免,路由太长书写, 过于麻烦。 为每一个路由, 命名别名。  使用 反向解析, 进行路由的配置。

    视图函数的处理:
    为了 避免与业务app的视图产生冲突,我将rbac 组件中原有的 views.py 删除, 创建一个 views 包。 包内分别 放置不同的视图模块。 角色管理, 用户管理 等,分别使用不同的模块,进行处理。
    新建 role.py 处理,角色相关的,所有视图函数。

    def role_list(request):
        '''
        角色列表的功能
        :param request:
        :return:
        '''
        role_queryset = models.Role.objects.all()
        return render(request, "rbac/role_list.html", locals())
    

     templates 也是, 为了避免与业务app 产生冲突。 同样的操作。 templates --> role --> ....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 role in role_queryset %}
                    <tr>
                        <td>{{ role.id }}</td>
                        <td>{{ role.title }}</td>
                        <td>
                            <a style="color: #333333;" href="/">
                                <i class="fa fa-edit" aria-hidden="true"></i></a>
                            <a style="color: #d9534f;" href="/"><i
                                    class="fa fa-trash-o"></i></a>
                        </td>
                    </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    {% endblock %}
    rbac emplates bac ole_list.html

    模板中的所有 按钮的, href 属性。 全部使用,反向解析。来做:

    href="{% url "rbac:role_add" %}"   不要忘了, 我们是通过 一级路由分发过来的, 所以要加上 rbac 名称空间的名字。

    2. 添加角色页面:role_add.html

    添加角色,与 查看相差无几。 唯一不同, 我使用,forms 组件, 进行验证,用户输入是否合法。
    从url 开始:

    urlpatterns = [
        re_path(r"^role/list/$", role.role_list, name="role_list"),
        re_path(r"^role/add/$", role.role_add, name="role_add"),
    ]
    

    forms组件,单独创建包,进行存放:

    因为我们是,直接对数据库,进行修改。 所以使用 class Meta: 进行确定。 我们要渲染的和要保存的 是那一张表。
    我这里只有一个title字段, 另一个是一个外键关系。 添加权限才用得到。

    from django import forms
    from django.core.exceptions import ValidationError,NON_FIELD_ERRORS
    from rbac import models
    
    
    class RolemodelForm(forms.ModelForm):
        '''
        角色 添加, fomr 组件
        '''
    
        class Meta:
            model = models.Role
            fields = ["title"]  # fields = "__all__"  就表示 对表中所有字段进行,操作
            # 直接指定,数据库中的 Role 角色表。  只对他的title 字段, 进行操作。
            widgets = {"title": forms.TextInput(attrs={"class": "form-control"})}
            # 为 input 框, 添加样式, 利用widgets小工具
    rbacMy_formsMy_forms.py

    视图函数:

    def role_add(request):
        '''
        添加角色的功能
        :param request:
        :return:
        '''
        forms = My_forms.RolemodelForm()
        if request.method == "POST":
            forms = My_forms.RolemodelForm(request.POST)
            if forms.is_valid():  # 验证成功
                forms.save()  # 进行保存
                return redirect(reverse("rbac:role_list"))  # 跳转到role_list
            else:
                return render(request, "rbac/role_add.html", {"forms": forms})  # 验证失败,返回带有错误信息的页面
        return render(request, "rbac/role_add.html", {"forms": forms})
    rbacviews ole.py   role_add(request):

    模板文件:

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

    使用forms 组件,进行渲染吗, 比较方便。 样式什么的自己挑。 使用post 发送添加数据的请求。

    这样, 当我们添加数据时, 通过验证之后, 就会自动保存到数据库中,  forms.save()  就能完成这件事。

    3. 编辑角色页面, role_edit.html

    思考:我是利用 form 组件。 循环进行渲染。  form中有几个字段,就会循环几次。 所以我们就让所有有的  添加编辑全部都是用同一个页面。  change.html  , 极大的减少,代码的书写长度。

    so  还是 url:

    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"),
    ]
    

     然后是:视图

    def role_edit(request, pk):
        '''
        编辑角色
        :param request:
        :param pk:   要修改的角色id
        :return:
        '''
        role_obj = models.Role.objects.filter(pk=pk).first()
        if not role_obj:
            return HttpResponse("角色不存在")
    
        if request.method == "POST":
            forms = My_forms.RolemodelForm(instance=role_obj, data=request.POST)
            if forms.is_valid():
                forms.save()
                return redirect(reverse("rbac:role_list"))
            else:
                return render(request, "rbac/change.html", {"forms": forms})
        forms = My_forms.RolemodelForm(instance=role_obj)  # 将查询出来的对象交给form组件, 进行渲染。
        # instance 就是接收一个 从数据库中,取出的模型表的这样一个数据。
    
        # 这里为什么返回的是,添加的页面? 因为添加个编辑一模一样, 只是input框中有数据而已。 而我现在的forms中已经有了数据
        return render(request, "rbac/change.html", {"forms": forms})
    rbacviews ole.py   role_edit(request, pk):

    这里有两个 forms 组件的参数, 解释一下:

    instance=role_obj  这个是接收从数据库中查询出来的 model 对象。 将他的数据放到forms组件中。
    data = request.POST 这个就是, 接收从前端页面, 发送过来的数据。 并对原来的数据库中的数据, 进行更新操作。
      就是models.Role.objects.filter(pk=pk).update(title=request.POST.get("title"))
    验证成功就 跳转到, 查看页面。 失败就还是返回 修改页面。 并且是带着错误信息返回的。

    4. 删除角色页面,

    思考: 删除我觉得,也应该有个提示。 而且 我所有的管理中, 都有删除页面。 so 搞一个全部用。

    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"),
    ]
    

     视图:

    def role_del(request, pk):
        '''
        删除操作, 需要给与用户提示。
        :param reuqest:
        :param pk:  要删除的角色id
        :return:
        '''
        origin_url = reverse("rbac:role_list")
        role_queryset = models.Role.objects.filter(pk=pk)
        if not role_queryset :
            return HttpResponse("角色不存在")
        if request.method == "POST":
            role_queryset.delete()
            return redirect(origin_url)
        return render(request, "rbac/role_del.html", {"cancel": origin_url})
    bacviews ole.py def role_del(request, pk):
    origin_url = reverse("rbac:role_list")   这个作用是, 和模板相关的。

    用户点击删除后, 提示 取消  和  确认。   取消的位置放置的是 一个 a 标签。
    而 a 标签的 跳转路径, 是由后台视图函数决定的,  way?   我要使用同一个页面, 进行所有的删除提示, 就不能将这个跳转的 url 写死。 不同的删除功能,点击取消后,应该跳转到不同的 查看页面。
      比如,   角色删除页面, 点击取消, 跳转到, 角色查看页面。  role_list.html
            客户删除页面, 点击取消, 跳转到, 客户查看页面。  costomer_list.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: 14px;"><i class="fa fa-warning" aria-hidden="true"></i>删除后不可恢复,请确定是否删除</p>
                    <div style="margin-top: 20px;">
                        <a href="{{ cancel }}" class="btn btn-default btn-sm">取 消</a>
                        <input type="submit" class="btn btn-danger btn-sm" value="确 认">
                    </div>
                </form>
            </div>
        </div>
    {% endblock %}
    bac emplates bac ole_del.html

     
    总结:
      - ModelForm
        1.  Class Meta  的 使用, 通过模型表指定 使用那张表的数据。  fields指定, 要创建field 对象的 表字段。
        2.  instance form对象接收,model对象。
        3. date  接收前端,发送而来的,需要进行验证的数据。
      - 根据 namespace 和 name 反向解析
        1. app下的url 命名的别名, 在使用是,需要带上,所属名称空间的名字,以冒号分割  reverse("rbac:role_list")
      - django模板的查找顺序
        1. django查找 templates 的顺序,是先从。主目录下找, 如果没有就根据settings中 app 的注册顺序,进行查找。
         未免rbac app与 业务app 发生冲突。 将rbac中的所有模板, 放入rbac包中套嵌进templates之中。  这样进行查     找模板时,  rbac之下的模板,都需要加上rbac/role_list.html  可以防止, 命名问题带来的,不期望的结果。

        2. 修改 编辑 删除。  进行重用,因为修改与编辑一模一样。 而删除提示页面,则是全部一样。

  • 相关阅读:
    星球居民突破 1800 人!
    测试数据管理
    解决InnoDB: Table mysql/innodb_index_stats has length mismatch in the column name table_name. Please run mysql_upgrade
    Warning: file_get_contents(): open_basedir restriction in effect. File(/proc/uptime) is not within the allowed path(s)解决方法
    Java终止线程的三种方式
    线程中断interrupt
    Linux 开启防火墙 避免非干系人误操作的处理
    Oracle12c 快速启动命令设置
    Docker 运行 Redis Rabbitmq seata-server ftp 的简单办法
    mysql8 CentOS7 简要安装说明
  • 原文地址:https://www.cnblogs.com/chengege/p/10704355.html
Copyright © 2020-2023  润新知