CRM——權限

1、引入權限組件

一、引入權限組件rbac

  拷貝以前寫好的rbac應用到CRM_demo項目下。css

  在settings中註冊rbac的app:html

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'crm.apps.CrmConfig',
    'stark.apps.StarkConfig',
    'rbac.apps.RbacConfig'
]

  settings中添加rabc中間件:python

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'rbac.serive.rbac.ValidPermission'
]

二、員工表Userinfo與rbac.User表作一對一關聯

from rbac.models import *

class UserInfo(models.Model):
    """
    員工表
    """
    name = models.CharField(verbose_name='員工姓名', max_length=16)
    username = models.CharField(verbose_name='用戶名', max_length=32)
    password = models.CharField(verbose_name='密碼', max_length=64)
    email = models.EmailField(verbose_name='郵箱', max_length=64)
    # 模仿 SQL 約束 ON DELETE CASCADE 的行爲,換句話說,刪除一個對象時也會刪除與它相關聯的外鍵對象。
    depart = models.ForeignKey(verbose_name='部門', to="Department", to_field="code", on_delete=models.CASCADE)
    user = models.OneToOneField(to=User, null=True, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

  因爲是臨時添加的字段,所以添加參數null=True。jquery

  而後完成數據遷移:web

manage.py@CRM_demo > makemigrations
manage.py@CRM_demo > migrate

2、給權限控制配置註冊stark

一、rbac/stark.py

from stark.service.stark import site,ModelStark
from .models import *

class UserConfig(ModelStark):
    list_display = ["name", "roles"]

site.register(User, UserConfig)

class RoleConfig(ModelStark):
    list_display = ["title", "permissions"]

site.register(Role, RoleConfig)

class PermissionConfig(ModelStark):
    list_display = ["id", "title", "url", "group", "action"]

site.register(Permission, PermissionConfig)
site.register(PermissionGroup)

二、添加權限組

  

三、添加權限

  

  

  注意:django

(1)輸入url字段過長

  原來在models.py中配置url的max_length=32這個長度不夠輸入所有路徑,所以將其改成max_length=64。bootstrap

(2)編輯操做的url和action

  編輯操做的url取的是crm應用的路徑在這裏是change,但action取的是rbac的操做分類是edit。session

{% extends 'base.html' %}

{% block con %}
    <h4>角色列表</h4>
    {% if per.add %}
        <a href="/roles/add" class="btn btn-primary">添加角色</a>
    {% endif %}
    <table class="table table-bordered table-striped">
        <tbody>
            {% for role in role_list %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ role.title }}</td>
                    <td>
                        {% if per.delete %}
                            <a href="/roles/delete/{{ user.pk }}" class="btn btn-danger">刪除</a>
                        {% endif %}
                        {% if per.edit %}
                            <a href="/roles/edit/{{ user.pk }}" class="btn btn-warning">編輯</a>
                        {% endif %}
                    </td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}
rbac/templates/roles.html

(3)查看學生成績添加

   這個是點擊學生表對應查看的,不能放在菜單欄中,所以不能將action設爲list.app

四、添加角色

  

五、添加用戶

  

六、給員工分配對應的user

  

  給每一個員工分配對應的user:ide

  

3、登陸、引入中間件

一、crm_demo/urls.py配置登陸url

from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from stark.service.stark import site
from crm import views

urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^stark/', site.urls),
    url(r'^login/', views.login)
]

二、crm/view.py視圖配置

from django.shortcuts import render, HttpResponse
# Create your views here.
from rbac.models import User
from rbac.service.permissions import initial_session

def login(request):
    if request.method == 'POST':
        user = request.POST.get("user")
        pwd = request.POST.get("pwd")

        user = User.objects.filter(name=user, pwd=pwd).first()

        if user:
            # 登陸成功
            request.session["user_id"] = user.pk
            # 註冊權限到session中
            initial_session(user, request)
            return HttpResponse("登陸成功")

    return render(request, "login.html", locals())

三、引入中間件

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'rbac.service.rbac.ValidPermission'
]

  至此權限控制已經實現了,當不一樣用戶登陸時,只能訪問具備權限的頁面。

4、頁面調整

一、拷貝base.html及調整

  將rbac應用下的base.html拷貝到CRM_demo項目下的templates裏,在這裏base.html是首先調用的,能夠在不修改rbac組件的狀況下調整base.html。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 引入 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    <link rel="stylesheet" href="/static/css/add.css">
    <link rel="stylesheet" href="/static/css/list.css">
    <style>
        .header {
            width: 100%;
            height: 60px;
            background-color: #336699;
        }

        .menu {
            background-color: bisque;
            position: fixed;
            top: 60px;
            bottom: 0px;
            left: 0px;
            width: 200px;
        }

        .content {
            position: fixed;
            top: 60px;
            bottom: 0;
            right: 0;
            left: 200px;
            overflow: auto; /* 滾動條 */
        }

        .menu_btn {
            font-size: 18px;
            text-align: center;
            padding: 30px 0;
        }
    </style>
</head>
<body>

<div class="header">
    <p>{{ user.name }}</p>
</div>
<div class="contain">
    {% load my_tags %}
    <div class="menu">
        {% get_menu request %}
    </div>
    <div class="content">
        {% block con %}

        {% endblock %}
    </div>
</div>
</body>
</html>
/templates/base.html

  被引入base.html的兩個css文件分別是/stark/add_view.html和/stark/list_view.html的css樣式。

input, select {
    display: block;
    width: 100%;
    height: 34px;
    padding: 6px 12px;
    font-size: 14px;
    line-height: 1.42857143;
    color: #555;
    background-color: #fff;
    background-image: none;
    border: 1px solid #ccc;
    border-radius: 4px;
    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
    -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
    -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
    transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}

.error {
    color: red;
}
stark/static/css/add.css
.filter a {
    text-decoration: none; /* 取消a標籤顏色 */
    color: grey;
}

.active {
    color: red !important; /* 提高優先級 */
}
stark/static/css/list.css

二、模板繼承

  此處修改的是stark子應用裏的模板。

(1)add_view.html

{% extends 'base.html' %}

{% block con %}
    <h3>添加頁面</h3>
    {% include 'form.html' %}
    <script>
        function pop(url) {
            window.open(url, "", "width=600, height=400, top=100, left=100")
        }
        function pop_response(pk, text, id) {
            console.log(pk, text, id);   // 10 人民郵電出版社 id_publish
            console.log(typeof text);  // string
            // 選擇哪個select標籤
            // option文本值和value值
            var $option = $('<option>');   // 建立標籤:<option></option>
            $option.html(text);      // 給標籤添加文本:<option>南京出版社</option>
            $option.val(pk);              // 給標籤添加value:<option value=111>南京出版社</option>
            $option.attr("selected", "selected");  // 添加屬性selected:<option value="111" selected="selected">南京出版社</option>
            $("#" + id).append($option);  // 將標籤添加到id="id_publish"的標籤中
        }
    </script>
{% endblock %}

(2)change_view.html

{% extends 'base.html' %}

{% block con %}
    <h3>編輯頁面</h3>
    {% include 'form.html' %}
{% endblock %}

(3)list_view.html

{% extends 'base.html' %}

{% block con %}
    <h4>數據列表</h4>
    <div class="container">
        <div class="row">
            <div class="col-md-9">
                {# <a href="add/" class="btn btn-primary">添加數據</a> #}
                <a href="{{ add_url }}" class="btn btn-primary">添加數據</a>
                {% if show_list.config.search_fields %}
                    <form action="" class="pull-right">
                        <input type="text" name="q" value="{{ show_list.config.key_word }}">
                        <button>搜索</button>
                    </form>
                {% endif %}
                <form action="" method="post">
                    {% csrf_token %}
                    <select name="action" id="" style="width: 200px; padding: 5px 8px; display: inline-block">
                        <option value="">-----------</option>
                        {% for item in show_list.get_action_list %}
                            <option value="{{ item.name }}">{{ item.desc }}</option>
                        {% endfor %}
                    </select>
                    <button type="submit" class="btn-info">Go</button>
                    <table class="table table-bordered table-striped">
                        <thead>
                        <tr>
                            {% for item in header_list %}
                                <th>{{ item }}</th>
                            {% endfor %}
                        </tr>
                        </thead>
                        <tbody>
                        {% for data in new_data_list %}
                            <tr>
                                {% for item in data %}
                                    <td>{{ item }}</td>
                                {% endfor %}
                            </tr>
                        {% endfor %}

                        </tbody>
                    </table>
                    <nav>
                        <ul class="pagination">
                            {{ show_list.pagination.page_html|safe }}
                        </ul>
                    </nav>
                </form>
            </div>
            {% if showlist.config.list_filter %}
                {# list_filter有值才顯示FILTER #}
                <div class="filter">
                    <h4>Filter</h4>
                    {% for filter_field, linktags in show_list.get_filter_linktags.items %}
                        <div class="well">
                            {# upper方法改成大寫 #}
                            <p>{{ filter_field.upper }}</p>
                            {% for link in linktags %}
                                <p>{{ link|safe }}</p>
                            {% endfor %}
                        </div>
                    {% endfor %}
                </div>
            {% endif %}
        </div>
    </div>
    <script>
        // 複選框全選
        $("#choice").click(function () {
            if ($(this).prop("checked")) {
                // 若是是選中狀態
                $(".choice_item").prop("checked", true);
            } else {
                $(".choice_item").prop("checked", false)
            }
        })
    </script>
{% endblock %}
View Code

(4)public.html

  在CRM_demo項目下的templates裏建立。

{% extends 'base.html' %}

{% block con %}
    <h3>公共客戶</h3>
    <div class="container">
        <div class="row">
            <div class="col-md-6">
                <table class="table table-bordered table-striped">
                    <thead>
                    <tr>
                        <th>ID</th>
                        <th>姓名</th>
                        <th>QQ</th>
                        <th>課程顧問</th>
                        <th>跟進詳情</th>
                        <th>確認跟進</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for customer in customer_list %}
                        <tr>
                            <td>{{ forloop.counter }}</td>
                            <td>{{ customer.name }}</td>
                            <td>{{ customer.qq }}</td>
                            <td>{{ customer.consultant }}</td>
                            <td><a href="/stark/crm/consultrecord/?customer={{ customer.pk }}">跟進記錄</a></td>
                            <td><a href="/stark/crm/customer/further/{{ customer.pk }}">確認跟進</a></td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
{% endblock %}
View Code

三、登陸後顯示效果

  

  側邊菜單都是顯示的組的名字:客戶管理。

四、修改顯示權限名稱

  修改/rbac/service/permissions.py:

def initial_session(user, request):
    """註冊權限到session中"""

    # 註冊菜單權限
    # permissions = user.roles.all().values("permissions__url", "permissions__group_id", "permissions__action","permissions__group__title").distinct()
    # 在這裏將權限組名改成權限名
    permissions = user.roles.all().values("permissions__url", "permissions__group_id", "permissions__action","permissions__title").distinct()
    print("permissions", permissions)

    menu_permission_list = []   # 菜單欄中權限列表:空列表
    for item in permissions:
        # item是裏面的字典
        if item["permissions__action"] == "list":
            # 列表裏面套一個個的元組,每一個元組包含url和權限組title
            # menu_permission_list.append((item["permissions__url"], item["permissions__group__title"]))
            # 改成權限名
            menu_permission_list.append((item["permissions__url"], item["permissions__title"]))

  登陸查看頁面:

  

五、rbac登陸問題

  測試中發現一個問題,當想調整權限和角色等信息時,登陸/stark/rbac/permission等頁面,全部帳戶都沒有訪問權限。

  這裏必須經過admin組件,添加系統管理員用戶和用戶組,添加訪問、編輯、刪除rbac相關頁面的權限。

相關文章
相關標籤/搜索