PERMISSIONS = [ ('view_device', 'Can view device'), ('add_device', 'Can add device'), ('change_device', 'Can change device'), ('delete_device', 'Can delete device'), ('view_maintenance_record', 'Can view maintenance record'), ('add_maintenance_record', 'Can add maintenance record'), ('change_maintenance_record', 'Can change maintenance record'), ('delete_maintenance_record', 'Can delete maintenance record'), ('view_fault_report', 'Can view fault report'), ('add_fault_report', 'Can add fault report'), ('change_fault_report', 'Can change fault report'), ('delete_fault_report', 'Can delete fault report'), ('view_maintenance_plan', 'Can view maintenance plan'), ('add_maintenance_plan', 'Can add maintenance plan'), ('change_maintenance_plan', 'Can change maintenance plan'), ('delete_maintenance_plan', 'Can delete maintenance plan'), ('view_device_image', 'Can view device image'), ('add_device_image', 'Can add device image'), ('change_device_image', 'Can change device image'), ('delete_device_image', 'Can delete device image'), ] for codename, name in PERMISSIONS: permission, created = Permission.objects.get_or_create(codename=codename, name=name) if created: print(f'Created permission {permission}') GROUPS = [ ('admin', ['view_device', 'add_device', 'change_device', 'delete_device', 'view_maintenance_record', 'add_maintenance_record', 'change_maintenance_record', 'delete_maintenance_record', 'view_fault_report', 'add_fault_report', 'change_fault_report', 'delete_fault_report', 'view_maintenance_plan', 'add_maintenance_plan', 'change_maintenance_plan', 'delete_maintenance_plan', 'view_device_image', 'add_device_image', 'change_device_image', 'delete_device_image']), ('manager', ['view_device', 'add_device', 'change_device', 'view_maintenance_record', 'add_maintenance_record', 'change_maintenance_record', 'view_fault_report', 'add_fault_report', 'change_fault_report', 'view_maintenance_plan', 'add_maintenance_plan', 'change_maintenance_plan', 'view_device_image', 'add_device_image', 'change_device_image']), ('user', ['view_device', 'view_maintenance_record', 'view_fault_report', 'view_maintenance_plan', 'view_device_image']), ] for group_name, permissions in GROUPS: group, created = Group.objects.get_or_create(name=group_name) if created: print(f'Created group {group}') for codename in permissions: permission = permission.objects.get(codename=codename) group.permissions.add(permission) print(f'Add permission {permission} to group {group}')

时间: 2023-12-31 20:06:41 浏览: 35
这是一段 Python 代码,它使用 Django 模型中的 Permission 和 Group 对象创建权限和用户组,并将权限分配给用户组。首先,它定义了一个包含权限代码和名称的元组列表 PERMISSIONS,一个包含用户组名称和该组所拥有的权限的元组列表 GROUPS。然后,对于每个权限元组,它使用 get_or_create() 方法查找具有给定codename和name的Permission对象。如果对象不存在,则会创建一个新的Permission对象,并将其存储在permission变量中。最后,如果新的Permission对象被创建,它会打印一条消息来指示成功创建了该权限。 接下来,对于每个用户组元组,它使用 get_or_create() 方法查找具有给定名称的Group对象。如果对象不存在,则会创建一个新的Group对象,并将其存储在group变量中。最后,对于该组所拥有的每个权限代码,它使用 get() 方法查找Permission对象,并使用 add() 方法将该权限添加到该组。如果成功添加,则会打印一条消息来指示成功将该权限添加到该组。
相关问题

buildozer.spec 申请内部存储权限 android.permissions = WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE 之后在程序中怎么写

在程序中,你可以使用以下代码来检查和获取内部存储权限: ```python import android.permissions as permissions from android.storage import primary_external_storage_path # 检查是否拥有内部存储权限 if not permissions.check_permission('android.permission.WRITE_EXTERNAL_STORAGE'): # 请求内部存储权限 permissions.request_permissions(['android.permission.WRITE_EXTERNAL_STORAGE']) # 获取内部存储路径 internal_storage_path = primary_external_storage_path() ``` 上述代码中,我们使用 `check_permission` 方法来检查是否具有 `WRITE_EXTERNAL_STORAGE` 权限,如果没有则调用 `request_permissions` 方法请求权限。 获取内部存储路径我们使用了 `primary_external_storage_path` 方法,它会返回一个字符串,表示内部存储的路径。你可以将这个路径作为文件的存储路径,例如: ```python file_path = internal_storage_path + '/myfile.txt' with open(file_path, 'w') as f: f.write('Hello, world!') ```

class UserCache(UserMixin): """用户表缓存""" userid: str username: str alternative_id: str homepage: str permissions: list def get_id(self): """使用替代用户ID,当账号信息发生变化时,替代ID更改为新的随机生成的值,确保他们的旧身份验证会话不再有效。""" return self.alternative_id @staticmethod def add_user_cache(alternative_id, **kwargs): """添加user缓存""" user_key = PROJECT_NAME + '-' + str(alternative_id) Redis().hset(user_key, 'alternative_id', str(alternative_id)) for name, value in kwargs.items(): Redis().hset(user_key, name, value) Redis().expire(user_key, SIGNIN_LIFETIME) return True @staticmethod def del_user_cache(alternative_id: str): """删除user缓存""" Redis().delete(PROJECT_NAME + '-' + alternative_id) return True @staticmethod def get_user_cache(alternative_id) -> object: """获取user缓存""" user_cache_dict = Redis(decode_responses=True).hgetall(PROJECT_NAME + '-' + str(alternative_id)) if user_cache_dict: user_cache = UserCache() user_cache.userid = user_cache_dict.get('userid') user_cache.username = user_cache_dict.get('username') user_cache.alternative_id = user_cache_dict.get('alternative_id') user_cache.homepage = user_cache_dict.get('homepage') user_cache.permissions = user_cache_dict.get('permissions').split(",") # redis里存的是字符串,转为列表 print(user_cache.permissions) return user_cache 帮我优化或者提建议,包括命名

首先,对于这个类的命名,建议在类名后面加上一个表示缓存的单词,可以是 `Cache` 或者 `Cacher` 等。比如 `UserCacher` 或 `UserCacheManager`。 其次,在 `add_user_cache` 方法中,`Redis()` 被多次调用,建议只实例化一次并在方法中传递。另外,在循环中多次调用 `Redis().hset`,这样做可能会导致性能问题。建议将要设置的值存储在一个字典中,然后一次性调用 `Redis().hmset` 方法。类似的,`del_user_cache` 方法中也可以重构类似的循环和多次调用 `Redis()` 的问题。 最后,在 `get_user_cache` 方法中,建议使用 `getattr` 函数来从字典中获取属性的值,这样可以避免在字典中没有找到指定的属性时引发 `AttributeError` 异常。另外,由于 `permissions` 可能为空字符串,建议在转换为列表前先进行非空判断。 综上所述,下面是一个经过优化的 `UserCacher` 类的示例代码: ``` class UserCacher(UserMixin): """用户表缓存管理""" userid: str username: str alternative_id: str homepage: str permissions: list @staticmethod def add_user_cache(redis, alternative_id, **kwargs): """添加用户缓存""" user_key = f"{PROJECT_NAME}-{alternative_id}" values = {"alternative_id": str(alternative_id)} values.update(kwargs) redis.hmset(user_key, values) redis.expire(user_key, SIGNIN_LIFETIME) return True @staticmethod def del_user_cache(redis, alternative_id: str): """删除用户缓存""" redis.delete(f"{PROJECT_NAME}-{alternative_id}") return True @staticmethod def get_user_cache(redis, alternative_id) -> object: """获取用户缓存""" user_cache_dict = redis.hgetall(f"{PROJECT_NAME}-{alternative_id}") if user_cache_dict: user_cache = UserCacher() user_cache.userid = user_cache_dict.get('userid') user_cache.username = user_cache_dict.get('username') user_cache.alternative_id = user_cache_dict.get('alternative_id') user_cache.homepage = user_cache_dict.get('homepage') user_cache.permissions = user_cache_dict.get('permissions') if user_cache.permissions: user_cache.permissions = user_cache.permissions.split(",") return user_cache ``` 希望对你有所帮助!

相关推荐

请帮我写一段单元测试,来测试以下代码:from flask import render_template, Blueprint, request, abort from flask_login import login_required, current_user from sqlalchemy import select, between, or_, desc from flbs.sign.sign_model import OperationLog, User from flbs.extensions import db from datetime import datetime dashboard_bp = Blueprint('dashboard', __name__) @dashboard_bp.before_request @login_required def add_operation_log(): # OperationLog.add_operation_log(current_user.userid, current_user.username) pass @dashboard_bp.route('/dashboard') def dashboard(): if 'd1' not in current_user.permissions: return abort(403) page = request.args.get('page', default=1) try: page = int(page) except ValueError: page = 1 daterange = request.args.get('daterange', default=datetime.now().strftime('%Y-%m-%d') + ' - ' + datetime.now().strftime( '%Y-%m-%d')) date_1 = daterange[:10] date_2 = daterange[-10:] + ' 23:59:59.999999' user = request.args.get('user', '').strip() module = request.args.get('module', '').strip() sql_query = select(OperationLog).where(between(OperationLog.c_date, datetime.strptime(date_1, "%Y-%m-%d"), datetime.strptime(date_2, "%Y-%m-%d %H:%M:%S.%f"))) if user: sql_query = sql_query.where(or_(OperationLog.userid == user, OperationLog.username == user)) if module: sql_query = sql_query.where( or_(OperationLog.endpoint.like("%" + module + "%"), OperationLog.full_path.like("%" + module + "%"))) sql_query = sql_query.order_by(desc(OperationLog.id)) # print(sql_query) paginated = db.paginate(select=sql_query, page=page, per_page=10) # 分页 pagination_query = {'daterange': daterange, 'user': user, 'module': module} return render_template('dashboard/dashboard.html', header_title='flask-sqlalchemy', tips='test pagination', user=user, daterange=daterange, module=module, paginated=paginated, endpoint=request.endpoint, total=paginated.total, full_path=request.full_path, pagination_query=pagination_query)

最新推荐

recommend-type

基于单片机的红外感应防盗报警器的硬件设计-本科毕业设计.doc

基于单片机的红外感应防盗报警器的硬件设计-本科毕业设计.doc
recommend-type

java基于ssm+vue量化积分管理系统源码 带毕业论文

【资源说明】 1、开发环境:ssm框架;内含Mysql数据库;VUE技术 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 4、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。
recommend-type

实例解析:敏捷测试实践与流程详解

"从一个实例详解敏捷测试的最佳实践 敏捷软件开发是一种以人为核心、迭代、逐步交付的开发方法论,强调快速响应变化。它起源于对传统瀑布模型的反思,以轻量级、灵活的方式处理项目的不确定性。敏捷联盟提出的四大价值原则强调了沟通、可工作的软件、与客户的合作以及对变化的响应,这些都是敏捷开发的核心理念。 敏捷测试是敏捷开发的重要组成部分,它贯穿于整个开发周期,而不仅仅是开发后期的验证。在敏捷开发中,测试人员不再仅仅是独立的检查者,而是变成了团队中的积极参与者,与开发人员紧密合作,共同确保产品质量。 第二部分:敏捷开发中的测试人员 在敏捷环境中,测试人员的角色发生了转变。他们不仅是缺陷的发现者,还是质量保证者和流程改进者。他们需要参与需求讨论,编写自动化测试脚本,进行持续集成,并与开发人员共享责任,确保每次迭代都能产出高质量的可交付成果。 测试人员需要具备以下能力: 1. 技术熟练:理解代码结构,能够编写自动化测试用例,熟悉各种测试框架。 2. 业务理解:深入理解产品功能和用户需求,能够有效地编写测试场景。 3. 沟通技巧:与开发人员、产品经理等团队成员有效沟通,确保测试反馈及时准确。 第三部分:敏捷开发中的测试流程 敏捷测试流程通常包括以下几个关键阶段: 1. 需求分析与计划:测试人员与团队一起确定需求,识别测试要点,规划测试活动。 2. 测试驱动开发(TDD):在编写代码之前先编写测试用例,确保代码满足预期功能。 3. 结对编程:测试人员与开发人员结对工作,共同编写代码和测试,减少错误引入。 4. 持续集成:频繁地将代码集成到主分支,每次集成都进行自动化测试,尽早发现问题。 5. 回归测试:每次修改或添加新功能后,执行回归测试以确保现有功能不受影响。 6. 用户验收测试(UAT):在每个迭代结束时,邀请真实用户或代表进行测试,确保产品符合用户期望。 通过这些步骤,敏捷测试旨在实现快速反馈、早期问题识别和持续改进。 总结 敏捷测试的最佳实践是通过密切协作、持续集成和自动化测试来提高效率和质量。测试人员需要具备技术与业务的双重能力,参与到开发的各个环节,以促进整个团队的质量意识。通过实例分析,我们可以看到敏捷测试如何在实际项目中发挥作用,帮助团队更高效地应对变化,提升软件产品的质量和用户满意度。 参考资料 1. Agile Alliance - The Agile Manifesto 2. Extreme Programming Explained, Embrace Change (Kent Beck) 3. Scrum Guide (Ken Schwaber & Jeff Sutherland) 4. Test-Driven Development: By Example (Kent Beck) 敏捷软件开发的不断发展和实践,使得测试不再只是开发的后续步骤,而是成为整个生命周期的内在部分,推动着团队向着更快、更高效、更高质量的目标前进。"
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

字符串匹配算法在文本搜索中的应用:从原理到实践

![字符串匹配算法Java](https://media.geeksforgeeks.org/wp-content/uploads/20230913105254/first.png) # 1. 字符串匹配算法概述** 字符串匹配算法是计算机科学中一种重要的技术,用于在给定的文本中查找特定模式或子串。它广泛应用于文本处理、数据挖掘和生物信息学等领域。字符串匹配算法的目的是快速高效地找到模式在文本中的所有匹配项,并返回匹配项的位置。 字符串匹配算法有多种类型,每种类型都有其独特的优点和缺点。最常见的算法包括朴素字符串匹配算法、KMP算法和Boyer-Moore算法。这些算法的复杂度和效率因模式
recommend-type

Python SciPy

**SciPy是一个开源的Python库,主要用于数学、科学和工程计算**。 SciPy建立在NumPy库的基础上,提供了一系列高级的数值算法和工具。这些工具旨在解决科学计算中的各种标准问题,包括但不限于优化、插值、统计、信号处理、线性代数等。SciPy的设计哲学是提供一套简洁、高效且可靠的工具,以促进科学家、工程师和数据分析师在各自领域的工作。 SciPy的功能可以分为多个子模块,每个子模块专注于特定的科学计算领域。例如,`scipy.integrate`子模块提供数值积分和微分方程求解的功能;`scipy.stats`则包含了广泛的统计分析函数,涉及概率分布、统计检验等;`scipy.
recommend-type

VIPer53驱动的高效机顶盒开关电源设计与性能优化

本文主要探讨了"基于VIPer53机顶盒开关电源的设计"。机顶盒作为家庭娱乐设备,对供电电源有着极高的要求,需要电源具备高效能、小型化、轻量化以及多路输出的特点。VIPer53是一款由ST公司开发的高度集成的离线开关集成电路,采用了纵向智能功率专利技术(VlPower),集成了增强型电流模式PWM控制器和高压MD-Mesh功率MOSFET,这使得其在功率密度和热管理方面表现出色。 VIPer53的核心特性包括高度集成,内部集成了控制电路和功率MOSFET,使得它能够满足机顶盒等应用中对功率转换效率、小型化设计以及电磁兼容性的严苛要求。其内部结构包括启动高压电流源、脉宽调制驱动器、保护功能(如过压、热关机、逐周限流和负载保护)等,确保了系统的稳定性和可靠性。 本文设计了一款基于VIPer53的5路输出、30W的机顶盒专用开关电源。实验结果显示,该电源具有优秀的性能指标,如高输出电压精度、负载调整率和电压调整率,证明了VIPer53在实际应用中的有效性。此外,由于集成度高,电源设计紧凑,且在电磁兼容性方面表现出良好的表现,符合机顶盒对于电源设计的严格要求。 设计过程涵盖了VIPer53的工作原理解析,详细介绍了其各个引脚的功能,如VDD、VDDcm、VDDoff、VDDreg和VDDovp等,以及如何通过连接外部元件来设定开关频率和实现过载保护。通过实际设计和测试,验证了VIPer53在机顶盒开关电源设计中的实用性和优势。 本文深入研究了VIPer53在机顶盒开关电源设计中的应用,不仅展示了其技术特点,还提供了具体的设计实例和实验验证,对于从事该领域研发和应用的工程师具有重要的参考价值。
recommend-type

"互动学习:行动中的多样性与论文攻读经历"

多样性她- 事实上SCI NCES你的时间表ECOLEDO C Tora SC和NCESPOUR l’Ingén学习互动,互动学习以行动为中心的强化学习学会互动,互动学习,以行动为中心的强化学习计算机科学博士论文于2021年9月28日在Villeneuve d'Asq公开支持马修·瑟林评审团主席法布里斯·勒菲弗尔阿维尼翁大学教授论文指导奥利维尔·皮耶昆谷歌研究教授:智囊团论文联合主任菲利普·普雷教授,大学。里尔/CRISTAL/因里亚报告员奥利维耶·西格德索邦大学报告员卢多维奇·德诺耶教授,Facebook /索邦大学审查员越南圣迈IMT Atlantic高级讲师邀请弗洛里安·斯特鲁布博士,Deepmind对于那些及时看到自己错误的人...3谢谢你首先,我要感谢我的两位博士生导师Olivier和Philippe。奥利维尔,"站在巨人的肩膀上"这句话对你来说完全有意义了。从科学上讲,你知道在这篇论文的(许多)错误中,你是我可以依
recommend-type

AHO-Corasick算法:多模式匹配的利器,揭秘其强大功能

![AHO-Corasick算法:多模式匹配的利器,揭秘其强大功能](https://img-blog.csdn.net/20170226151731867) # 1. AHO-Corasick算法简介 AHO-Corasick算法是一种多模式匹配算法,它可以在线性的时间复杂度内在文本中查找多个模式。它由Alfred V. Aho和Margaret J. Corasick于1975年提出,是一种广泛用于文本搜索和信息检索的经典算法。 AHO-Corasick算法基于有限状态自动机(FSM),它将模式编译成一个FSM,然后使用失效函数和跳转函数在文本中进行匹配。失效函数用于处理模式不匹配的情
recommend-type

三极管输出特性曲线图

三极管的输出特性曲线图,通常指的是晶体管在不同的偏置条件下,其集电极电流(Ic)与基极电压(Vb)之间的关系图形。这种图表主要包括三个区域: 1. **截止区** (Cut-off region):当基极电压小于某个阈值(称为死区电压),无论基极电流如何变化,集电极电流都很小接近于零,这时三极管完全停止导通。 2. **线性放大区** (Active region):当基极电压超过死区电压,增加基极电流可以适度地增大集电极电流,此时输出是线性的,适合做放大作用。这个区域也叫放大区。 3. **饱和区** (Saturation region):随着基极电压进一步升高,基极电流不再显著影响