该文章收录专栏
✨—Django从(图文并茂轻松上手教程)专栏—✨!!🎏内容:
✨【Djang | 增删改查】学生系统案例✨
✨【Django | 项目搭建】快速搭建自己的项目✨
✨【Django | allauth】登录_注册_邮箱验证_密码邮箱重置✨
✨【Django | allauth】useprofile 用户模型扩展✨
✨【Django | allauth】重写allauth重置密码方法✨
✨【Django | 开发】面试招聘信息网站(快速搭建核心需求)✨
✨【Django | 开发】面试招聘信息网站(增加csv,excel导出&日志管理功能)✨
✨【Django | 开发】面试招聘信息网站(处理产品细节和权限&美化页面样式)✨
get_list_fieldsets
控制admin
选项option
中的fieldsets
实现预期效果:
代码实现(核心代码)
# 定义集合的字段列表
default_fieldsets = (
# 第一个元素表示分组展现的名字,第二元素是一个map
·······
)
default_fieldsets_hr = (·······)
# 定义集合的字段列表
default_fieldsets_second = (·······)
# 定义集合的字段列表
default_fieldsets_first = (·······)
def get_fieldsets(self, request, obj=None):
group_name = self.get_group_name(request.user)
# obj 是对应修改对象,和action方法queryset一样
if 'interviewer' in group_name and request.user == obj.first_interviewer_user: # 判断是否对应一面面试官
logger.info("The interviewer is the first interviewer for user %s"% obj.user_name)
return default_fieldsets_first
elif 'interviewer' in group_name and request.user == obj.second_interviewer_user:
logger.info("The interviewer is the second interviewer for user %s" % obj.user_name)
return default_fieldsets_second
elif request.user.is_superuser or 'HR' in group_name:
logger.info("The interviewer is the HR for user %s or superuser" % obj.user_name)
return default_fieldsets_hr
return default_fieldsets
def get_group_name(self, user):
group_name = []
for g in user.groups.all(): # 循环groups对象列表
group_name.append(g.name) # 附加对象的名字
return group_name
fieldset
代码过长,我们将设置的fieldset
放到脚本candidate_fieldset
脚本文件中,直接引入进来。HR 和超级用户
一面面试官
二面面试官
get_queryset
进行条件判断,并借助Q对象
对数据库SQL语句
进行or and
组合实现需求from django.db.models import Q
# 列表页显示默认先运行get_queryset,没有重写则全部显示
# 此时显示的数据集是对于Candidate模型的,不影响其他模型
def get_queryset(self, request):
qs = super(CandidateAdmin, self).get_queryset(request)
group_name = self.get_group_name(request.user)
# hr or superuser
if 'HR' in group_name or request.user.is_superuser:
return qs
# interviewer
return Candidate.objects.filter( # Q对象 可进行and or 配合位或运算符
Q(first_interviewer_user=request.user) | Q(second_interviewer_user=request.user))
成功实现
在添加群组时我们为
interviewer
群组添加了增删改查应聘者的权限,这里再为普通面试官添加不可导出为csv
action行为 的权限以及不可删除对象 (delete_selected
)的权限
Candidate模型
中 Meta
为其设置自定义权限(元组))get_actions
)https://docs.djangoproject.com/zh-hans/4.0/ref/contrib/admin/actions/
(各种方法文档都有例子)Candidate模型
中 Meta
为其设置自定义权限(元组))
·······
class Meta:
db_table = 'candidate'
verbose_name = '应聘者'
verbose_name_plural = '应聘者' # 复数形式
permissions = (
('export_as_csv_or_excel', "Can export candidate list"),
('notify_interviewer', "Can notify interviewer")
)
······
action装饰器
和ModelAdmin类
加上权限设置( permissions 的值必须是一个 列表或元组!传一个字符串会拆成各个字符)
# 注册为 action permissions 的值必须是一个 列表或元组!传一个字符串会拆成各个字符
@admin.action(description='导出为csv文件', permissions=('export_as_csv_or_excel'))
def export_model_as_csv(modeladmin, request, queryset):
·······
# 注册为 action
@admin.action(description='导出为excel文件', permissions=('export_as_csv_or_excel'))
def export_model_as_excel(modeladmin, request, queryset):
······
You can specify any other value as long as you implement a corresponding has_[value]_permission(self, request) method on the ModelAdmin.(注意:这里的value就是你设置的权限)
admin
代码总体代码思想,先在
model模型
添加Meta
信息,数据库同步则会添加在群组权限设置中,
然后对action行为
添加permission
权限,接着还必须要在modeladmin
添加函数has_value_permission
判断登录user
是否has_perm
(拥有权限),返回值为boolean
, 我们可以看看permission 模型代码
# 全局禁用删除对象,需要使用需要在modeladmin加上该action
# admin.site.disable_action('delete_selected') 不建议使用,可以通过权限设置
@admin.register(Candidate)
class CandidateAdmin(admin.ModelAdmin):
# import actions to use
actions = [export_model_as_csv, export_model_as_excel, 'delete_selected']
def has_export_as_csv_or_excel_permission(self, request):
"""Does the user have the export permission?"""
opts = self.opts
# return a boolean 判断是否权限 模型所在应用 权限名
return request.user.has_perm("%s.%s" % (opts.app_label, "export_as_csv_or_excel")) # 是否有对应权限
······
这里的opts
参数其实就是对应model
的Meta
效果
现在还无法看到权限,因为model模型
的Meta
信息还没有同步到数据库(如果数据库auth用户验证模块没有这个定义,这里是不显示的)
数据迁移两把斧运行
成功
interview
创建脚本dingtalk.py
# coding=utf-8
# 引入聊天机器人
from dingtalkchatbot.chatbot import DingtalkChatbot
from django.conf import settings
def send(message, at_mobiles=[]):
# 引用settings 中配置钉钉群中配置消息通知的WEB hook
webhook = settings.DINGTALK_WEB_HOOK
# 初始化机器人小丁 方法一
xiaoding = DingtalkChatbot(webhook)
# 方法二
# xiaoding = DingtalkChatbot(webhook,secret=secret)
# Text消息 @所有人
xiaoding.send_text(msg=('面试通知:%s' % message), at_mobiles=at_mobiles)
将Webhook 卸载setting中
使用shell
测试
In [2]: import interview.dingtalk
In [3]: interview.dingtalk.send("通知!请哈利波速速救急")
也可以@面试官
In [6]: interview.dingtalk.send("通知!请哈利波速速救急",['1343187782'])
在实际中,我们希望直接通知最近需要面试候选人得面试官,所以我们为应聘者添加一个action,被选中得应聘者可以直接发送到对应一面或二面面试官。
admin.py
# 导入发送消息
from .dingtalk import send
# 注册为 action
@admin.action(description='钉钉通知面试官', permissions=('notify_interviewer',))
def notify_interviewer(modeladmin, request, queryset):
# 面试官对象
candidates = ""
interviewer = []
at_mobiles = []
for candidate in queryset:
candidates = candidate.user_name + ',' + candidates
if candidate.first_interviewer_user is not None:
interviewer.append(candidate.first_interviewer_user)
if candidate.second_interviewer_user is not None:
interviewer.append(candidate.second_interviewer_user)
# 集合去重
interviewer = set(interviewer)
for mobile in interviewer:
at_mobiles.append(mobile.profile.tel)
logger.info("%s interviewer have been notice" % len(interviewer))
logger.info(at_mobiles)
logger.info(interviewer)
send("%s 准备面试,以下面试官请准备面试工作" % candidates, at_mobiles=at_mobiles)
@admin.register(Candidate)
class CandidateAdmin(admin.ModelAdmin):
·······
# import actions to use
actions = [export_model_as_csv, export_model_as_excel, notify_interviewer]
def has_notify_interviewer_permission(self, request):
"""Does the user have the export permission?"""
opts = self.opts
# return a boolean 判断是否权限 模型所在应用 权限名
return request.user.has_perm("%s.%s" % (opts.app_label, "notify_interviewer")) # 是否有对应权限
效果
🤞到这里,如果还有什么疑问🤞
🎩欢迎私信博主问题哦,博主会尽自己能力为你解答疑惑的!🎩
🥳如果对你有帮助,你的赞是对博主最大的支持!!🥳