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 06 Python
python字符串过滤性能比较5种方法
Jun 22 Python
python中利用队列asyncio.Queue进行通讯详解
Sep 10 Python
django rest framework之请求与响应(详解)
Nov 06 Python
Python实现PS滤镜中马赛克效果示例
Jan 20 Python
tensorflow 打印内存中的变量方法
Jul 30 Python
python pandas读取csv后,获取列标签的方法
Nov 12 Python
对python捕获ctrl+c手工中断程序的两种方法详解
Dec 26 Python
django mysql数据库及图片上传接口详解
Jul 18 Python
Python日志处理模块logging用法解析
May 19 Python
python爬取youtube视频的示例代码
Mar 03 Python
Python绘制散乱的点构成的图的方法
Apr 21 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
分页显示Oracle数据库记录的类之二
2006/10/09 PHP
PHP随机生成随机个数的字母组合示例
2014/01/14 PHP
PHP实现简单爬虫的方法
2015/07/29 PHP
PHP数组游标实现对数组的各种操作详解
2016/01/26 PHP
作为PHP程序员你要知道的另外一种日志
2018/07/30 PHP
JavaScript Timer实现代码
2010/02/17 Javascript
Javascript动态绑定事件的简单实现代码
2010/12/25 Javascript
基于jQuery的前端数据通用验证库
2011/08/08 Javascript
javascript的函数作用域
2014/11/12 Javascript
jQuery中outerWidth()方法用法实例
2015/01/19 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
详解Node.js开发中的express-session
2017/05/19 Javascript
javascript实现非常简单的小数取整功能示例
2017/06/13 Javascript
详解在vue-cli项目中安装node-sass
2017/06/21 Javascript
解决vue跨域axios异步通信问题
2019/04/17 Javascript
微信小程序 简易计算器实现代码实例
2019/09/02 Javascript
解决在Vue中使用axios POST请求变成OPTIONS的问题
2020/08/14 Javascript
js实现三角形粒子运动
2020/09/22 Javascript
[01:48]DOTA2 2015国际邀请赛中国区预选赛第二日战报
2015/05/27 DOTA
Python实现批量把SVG格式转成png、pdf格式的代码分享
2014/08/21 Python
Python的Django框架可适配的各种数据库介绍
2015/07/15 Python
pycharm恢复默认设置或者是替换pycharm的解释器实例
2018/10/29 Python
python3+opencv3识别图片中的物体并截取的方法
2018/12/05 Python
linux中如何使用python3获取ip地址
2019/07/15 Python
python使用opencv实现马赛克效果示例
2019/09/28 Python
win10下python2和python3共存问题解决方法
2019/12/23 Python
超全Python图像处理讲解(多模块实现)
2020/04/13 Python
通过Python实现Payload分离免杀过程详解
2020/07/13 Python
在Python3.74+PyCharm2020.1 x64中安装使用Kivy的详细教程
2020/08/07 Python
畜牧兽医本科生个人的自我评价
2013/10/11 职场文书
小学生我的梦想演讲稿
2014/08/21 职场文书
商务代表岗位职责
2015/02/15 职场文书
聋哑人盗窃罪辩护词
2015/05/21 职场文书
2015选调生工作总结
2015/07/24 职场文书
涨工资申请书应该怎么写?
2019/07/08 职场文书
Python中的socket网络模块介绍
2022/07/23 Python