Xadmin+rules实现多选行权限方式(级联效果)


Posted in Python onApril 07, 2020

行权限配置

xadmin中配置且不需要数据库支持,

安装并配置rules

pip安装:

pip install rules

配置settings.py

# settings.py
INSTALLED_APPS = (
  # ...
  'rules',
)
AUTHENTICATION_BACKENDS = (
  'rules.permissions.ObjectPermissionBackend',
  'django.contrib.auth.backends.ModelBackend',
)

配置models.py

# models.py
class CompanyUser(models.Model):
  users = models.OneToOneField(User, verbose_name='用户名', on_delete=User)
  is_admin = models.BooleanField('是否运营人员', default=False)
  category_code = models.ManyToManyField(user, verbose_name='可管理', max_length=20, blank=True, default='')
  #ForeignKey为单选,ManyToManyField为多选.

  def __str__(self):
    return str(self.users)

  class Meta:
    verbose_name = '管理账号'
    verbose_name_plural = verbose_name
    
    
    
class user(models.Model):
  title = models.CharField(max_length=50, verbose_name="文章标题")
  author = models.CharField(max_length=50, null=True, blank=True, verbose_name='文章作者')
  #category = models.ForeignKey(Category, verbose_name="所属类别", null=True, blank=True, on_delete=Category)(多选时启用)
  content = UEditorField(verbose_name="文章内容", imagePath='static/img/', filePath="static/img/", upload_settings={"imageMaxSize": 1204000}, default='')
  click_num = models.IntegerField(default=0, verbose_name="浏览量", )
  image = models.FileField(max_length=200, verbose_name="文章图片", null=True, blank=True, upload_to='static/img', default=None)
  add_time = models.DateField(default=datetime.now, verbose_name="添加时间")

  def __str__(self):
    return self.title

  class Meta:
    verbose_name = '文章信息'
    verbose_name_plural = verbose_name

使用rule

在models的同级目录新增rules.py,配置该app相关的对象权限

# rules.py
#必须将以下内容添加到rules.py文件的顶部,否则在尝试导入django-rules本身时会出现导入错误。
from __future__ import absolute_import 

import rules

# 使用修饰符@rules.predicate自定义predicates(判断),返回True表示有权限,False表示无权限

@rules.predicate
def is_colleague(user, entry):
  if not entry or not hasattr(user, 'companyuser'):
    return False
  return entry.category_code == user.companyuser.category_code


@rules.predicate
def is_admin(user):
  if not hasattr(user, 'companyuser'):
    return False
  return user.companyuser.is_admin


is_admins = is_admin | rules.is_superuser | is_colleague

# 设置Rules

rules.add_rule('can_view_user', is_admins)
rules.add_rule('can_delete_user', is_admins)
rules.add_perm('can_change_user', is_admins)

# 设置Permissions

rules.add_perm('data_import.view_user', is_admins)
rules.add_perm('data_import.delete_user', is_admins)
rules.add_perm('data_import.add_user', is_admins)
rules.add_perm('data_import.change_user', is_admins)

adminx.py设置

必须引用rules文件,权限规则才会生效,对于xadmin,添加from .rules import *即可.

# adminx.py
from __future__ import absolute_import
import xadmin
from xadmin import views
from lice.models import *
from .rules import *


class UserAdmin(object):
  list_display = 'title',
  search_fields = 'title', 'content',
  list_filter = 'category',
  readonly_fields = 'click_num',
  exclude = 'add_time',
  style_fields = {"content": "ueditor"}
  
  def queryset(self):
    qs = super(UserAdmin, self).queryset()
    if self.request.user.is_superuser or is_admin(self.request.user):
      return qs
    try:
      print('-------------------')
      print(qs)#打印一下qs的结果
      print('-------------------')
      print(CompanyUser.objects.get(users=self.request.user).category_code.filter())
      #打印登录账号的可管理内容
      print('-------------------')
      return CompanyUser.objects.get(users=self.request.user).category_code.filter()
    except AttributeError:
      return None
      
      
class CompanyUserAdmin(object):
  pass
      
xadmin.site.register(CompanyUser, CompanyUserAdmin)
xadmin.site.register(user, UserAdmin)

效果展示:

Xadmin+rules实现多选行权限方式(级联效果)

Xadmin+rules实现多选行权限方式(级联效果)

需先在管理账号里为账号添加可管理内容

Xadmin+rules实现多选行权限方式(级联效果)

大功告成~

行权限配置(多选)

若要达到级联多选效果需要在原基础上修改models.py并添加 views.py\urls.py及js即可实现

新建一个类别模型(可对比上面的模型),并在已有的CompanyUser中添加类别字段

models.py

# models.py
class CompanyUser(models.Model):
  users = models.OneToOneField(User, verbose_name='用户名', on_delete=User)
  is_admin = models.BooleanField('是否运营人员', default=False)
  category = models.ForeignKey(Category, on_delete=Category, verbose_name='可管理分类', max_length=20, null=True, blank=True, default='')
  category_code = models.ManyToManyField(user, verbose_name='可管理文章', max_length=20, null=True, blank=True, default='')
  #ForeignKey为单选,ManyToManyField为多选.

  def __str__(self):
    return str(self.users)

  class Meta:
    verbose_name = '管理账号'
    verbose_name_plural = verbose_name
    
class Category(models.Model):
  name = models.CharField(max_length=20, verbose_name="文章类别")
  add_time = models.DateField(default=datetime.now, verbose_name="添加时间")

  def __str__(self):
    return self.name

  class Meta:
    verbose_name = "类别信息"
    verbose_name_plural = verbose_name

F12找到一级目录和二级目录的select中ID

Xadmin+rules实现多选行权限方式(级联效果)

我的一级目录id=id_category,二级目录id=id_category_code

下面开始创建一个新的js文件

并将id替换到js文件中

#名字随便.我的是xadmin.js
# xadmin.js
$('#id_category').change(function () {
  var module = $('#id_category').find('option:selected').val(); //获取父级选中值
  $('#id_category_code')[0].selectize.clearOptions();// 清空子级
  if (module)
    $.ajax({
      type: 'get',
      url: '/select/one_two/?module=' + module,
      data: '',
      async: true,
      beforeSend: function (xhr, settings) {
        xhr.setRequestHeader('X-CSRFToken', '{{ csrf_token }}')
      },
      success: function (data) {
        data = JSON.parse(data.data)//将JSON转换
        console.log(data);
        for (var i = 0; i < data.length; i++) {

          var test = {text: data[i].fields.title, value: data[i].pk, $order: i + 1}; //遍历数据,拼凑出selectize需要的格式
          $('#id_category_code')[0].selectize.addOption(test); //添加数据
        }
      },
    })
  else {
    #如果一级目录为分配则遍历所有子目录可选项
    $.ajax({
      type: 'get',
      url: '/select/one_two/?module=all',
      data: '',
      async: true,
      beforeSend: function (xhr, settings) {
        xhr.setRequestHeader('X-CSRFToken', '{{ csrf_token }}')
      },
      success: function (data) {
        data = JSON.parse(data.data)//将JSON转换
        console.log(data);
        for (var i = 0; i < data.length; i++) {

          var test = {text: data[i].fields.title, value: data[i].pk, $order: i + 1}; //遍历数据,拼凑出selectize需要的格式
          $('#id_category_code')[0].selectize.addOption(test); //添加数据
        }
      },
    })
  }
})

将js中此行的 ‘title' 替换为你想要显示的数据库字段名 有两个(20行|40行)

var test = {text: data[i].fields.title, value: data[i].pk, $order: i + 1}; //遍历数据,拼凑出selectize需要的格式

将写好的js文件放入xadmin\static\xadmin\js中,如图所示

Xadmin+rules实现多选行权限方式(级联效果)

找到xadmin\widgets.py,将js添加进去(这是xadmin的搜索类)

Xadmin+rules实现多选行权限方式(级联效果)

添加视图

view.py

#导入serializers
from django.core import serializers
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views import View
# 二级联动View函数
class SelectView(LoginRequiredMixin, View):
  def get(self, request):
    # 通过get得到父级选择项
    id_category = request.GET.get('module', '')
    # 筛选出符合父级要求的所有子级,因为输出的是一个集合,需要将数据序列化 serializers.serialize()
    if id_category == 'all':
      id_category_code = serializers.serialize("json", user.objects.all())s
      #通过Ajax请求查询
    else:
      id_category_code = serializers.serialize("json", user.objects.filter(category=int(id_category)))
    # 判断是否存在,输出
    if id_category_code:
      return JsonResponse({'data': id_category_code})

url.py

from users.views import SelectView
url(r'^select/one_two/', SelectView.as_view(), name='one_two'),

效果展示:

操作方法同上

Xadmin+rules实现多选行权限方式(级联效果)

Xadmin+rules实现多选行权限方式(级联效果)

Xadmin+rules实现多选行权限方式(级联效果)

完成!

以上这篇Xadmin+rules实现多选行权限方式(级联效果)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
编程语言Python的发展史
Sep 26 Python
Python实现获取网站PR及百度权重
Jan 21 Python
Python脚本在Appium库上对移动应用实现自动化测试
Apr 17 Python
Linux 下 Python 实现按任意键退出的实现方法
Sep 25 Python
python实现list元素按关键字相加减的方法示例
Jun 09 Python
python微信跳一跳系列之棋子定位像素遍历
Feb 26 Python
Python实现计算字符串中出现次数最多的字符示例
Jan 21 Python
python中selenium操作下拉滚动条的几种方法汇总
Jul 14 Python
python标准库sys和OS的函数使用方法与实例详解
Feb 12 Python
解决pyecharts运行后产生的html文件用浏览器打开空白
Mar 11 Python
python3实现名片管理系统(控制台版)
Nov 29 Python
python实现ping命令小程序
Dec 28 Python
Django Xadmin多对多字段过滤实例
Apr 07 #Python
解决Django部署设置Debug=False时xadmin后台管理系统样式丢失
Apr 07 #Python
解决Python中报错TypeError: must be str, not bytes问题
Apr 07 #Python
Pycharm及python安装详细步骤及PyCharm配置整理(推荐)
Jul 31 #Python
django 实现简单的插入视频
Apr 07 #Python
django实现后台显示媒体文件
Apr 07 #Python
Python搭建Keras CNN模型破解网站验证码的实现
Apr 07 #Python
You might like
第一个无线电台是由谁发明的
2021/03/01 无线电
php使用cookie显示用户上次访问网站日期的方法
2015/01/26 PHP
php实现博客,论坛图片防盗链的方法
2016/10/15 PHP
thinkphp实现把数据库中的列的值存到下拉框中的方法
2017/01/20 PHP
PHP中include()与require()的区别说明
2017/02/14 PHP
PHP异常处理定义与使用方法分析
2017/07/25 PHP
JQuery select控件的相关操作实现代码
2012/09/14 Javascript
Javascript异步编程模型Promise模式详细介绍
2014/05/08 Javascript
jquery验证邮箱格式是否正确实例讲解
2015/11/16 Javascript
JQuery validate 验证一个单独的表单元素实例
2017/02/17 Javascript
JS实现合并json对象的方法
2017/10/10 Javascript
10分钟彻底搞懂Http的强制缓存和协商缓存(小结)
2018/08/30 Javascript
js代码规范之Eslint安装与配置详解
2018/09/08 Javascript
解决layer.open后laydate失效的问题
2019/09/06 Javascript
详解JavaScript作用域、作用域链和闭包的用法
2020/09/03 Javascript
Python格式化css文件的方法
2015/03/10 Python
常见的在Python中实现单例模式的三种方法
2015/04/08 Python
深入解析Python的Tornado框架中内置的模板引擎
2016/07/11 Python
Python Paramiko模块的安装与使用详解
2016/11/18 Python
Python编程实现及时获取新邮件的方法示例
2017/08/10 Python
Django使用消息提示简单的弹出个对话框实例
2019/11/15 Python
Python3.7基于hashlib和Crypto实现加签验签功能(实例代码)
2019/12/04 Python
查看端口并杀进程python脚本代码
2019/12/17 Python
用python对excel进行操作(读,写,修改)
2020/12/25 Python
GANT英国官方网上商店:甘特衬衫
2018/02/06 全球购物
瑞典度假品牌:OAS
2019/05/28 全球购物
儿科护士实习自我鉴定
2013/10/17 职场文书
农村婚礼证婚词
2014/01/08 职场文书
图书室管理制度
2014/01/19 职场文书
药剂专业自荐书
2014/06/20 职场文书
法制宣传标语
2014/06/23 职场文书
2015自愿离婚协议书范本
2015/01/28 职场文书
行政司机岗位职责
2015/04/10 职场文书
MySQL8.0.18配置多主一从
2021/06/21 MySQL
使用redis生成唯一编号及原理示例详解
2021/09/15 Redis
中国十大神话动漫电影排行榜 哪吒登顶 白蛇缘起排第七
2022/03/21 国漫