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 25 Python
python决策树之C4.5算法详解
Dec 20 Python
python pandas dataframe 按列或者按行合并的方法
Apr 12 Python
解决win64 Python下安装PIL出错问题(图解)
Sep 03 Python
windows下numpy下载与安装图文教程
Apr 02 Python
django页面跳转问题及注意事项
Jul 18 Python
python科学计算之narray对象用法
Nov 25 Python
如何基于python测量代码运行时间
Dec 25 Python
关于Python 中的时间处理包datetime和arrow的方法详解
Mar 19 Python
Python 使用生成器代替线程的方法
Aug 04 Python
python 根据列表批量下载网易云音乐的免费音乐
Dec 03 Python
python matlab库简单用法讲解
Dec 31 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
php中session退出登陆问题
2014/02/27 PHP
php实现的一个简单json rpc框架实例
2015/03/30 PHP
YII视图整合kindeditor扩展的方法
2016/07/13 PHP
加载jQuery后$冲突的解决办法
2010/07/09 Javascript
JSON.stringify 语法实例讲解
2012/03/14 Javascript
javascript中将Object转换为String函数代码 (json str)
2012/04/29 Javascript
javascript动态加载实现方法一
2012/08/22 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
Extjs grid添加一个图片状态或者按钮的方法
2014/04/03 Javascript
JavaScript获取表单enctype属性的方法
2015/04/02 Javascript
JavaScript缓冲运动实现方法(2则示例)
2016/01/08 Javascript
JS制作适用于手机和电脑的通知信息效果
2016/10/28 Javascript
js获取元素的偏移量offset简单方法(必看)
2017/07/05 Javascript
浅谈Angular路由守卫
2017/08/26 Javascript
小程序清理本地缓存的方法
2018/08/17 Javascript
nodejs中express入门和基础知识点学习
2018/09/13 NodeJs
Vue常见面试题整理【值得收藏】
2018/09/20 Javascript
vue中input的v-model清空操作
2019/09/06 Javascript
JavaScript实现鼠标经过表格某行时此行变色
2020/11/20 Javascript
零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers
2014/11/05 Python
django中send_mail功能实现详解
2018/02/06 Python
Python Dataframe 指定多列去重、求差集的方法
2018/07/10 Python
python实现文件批量编码转换及注意事项
2019/10/14 Python
django-crontab实现服务端的定时任务的示例代码
2020/02/17 Python
详解python中GPU版本的opencv常用方法介绍
2020/07/24 Python
纯css3实现的鼠标悬停动画按钮
2014/12/23 HTML / CSS
美国大型的健身社区和补充商店:Bodybuilding.com
2016/09/06 全球购物
BCBG官网:BCBGMAXAZRIA
2017/12/29 全球购物
Hobbs官方网站:英国奢华女性时尚服装
2020/02/22 全球购物
开办饭店创业计划书
2013/12/28 职场文书
八年级英语教学反思
2014/01/09 职场文书
我的祖国演讲稿
2014/05/04 职场文书
父亲节寄语大全
2015/02/27 职场文书
社区服务活动感想
2015/08/11 职场文书
2016年小学生清明节广播稿
2015/12/17 职场文书
python tkinter Entry控件的焦点移动操作
2021/05/22 Python