拷貝以前寫好的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' ]
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
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
原來在models.py中配置url的max_length=32這個長度不夠輸入所有路徑,所以將其改成max_length=64。bootstrap
編輯操做的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 %}
這個是點擊學生表對應查看的,不能放在菜單欄中,所以不能將action設爲list.app
給每一個員工分配對應的user:ide
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) ]
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' ]
至此權限控制已經實現了,當不一樣用戶登陸時,只能訪問具備權限的頁面。
將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>
被引入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; }
.filter a { text-decoration: none; /* 取消a標籤顏色 */ color: grey; } .active { color: red !important; /* 提高優先級 */ }
此處修改的是stark子應用裏的模板。
{% 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 %}
{% extends 'base.html' %} {% block con %} <h3>編輯頁面</h3> {% include 'form.html' %} {% endblock %}
{% 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 %}
在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 %}
側邊菜單都是顯示的組的名字:客戶管理。
修改/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"]))
登陸查看頁面:
測試中發現一個問題,當想調整權限和角色等信息時,登陸/stark/rbac/permission等頁面,全部帳戶都沒有訪問權限。
這裏必須經過admin組件,添加系統管理員用戶和用戶組,添加訪問、編輯、刪除rbac相關頁面的權限。