写点什么

【Django | 开发】面试招聘信息网站(划分面试官权限 & 集成钉钉消息)

  • 2022 年 8 月 30 日
    广东
  • 本文字数:3818 字

    阅读完需:约 13 分钟


🤵‍♂️ 个人主页: @计算机魔术师👨‍💻 作者简介:CSDN 内容合伙人,全栈领域优质创作者。


🌐 推荐一款找工作神器网站: 牛客网🎉🎉|笔试题库|面试经验|实习招聘内推 还没账户的小伙伴 速速点击链接跳转牛客网登录注册 开始刷爆题库,速速通关面试吧🙋‍♂️


该文章收录专栏---【Django | 项目开发】从入门到上线 专栏---


@[toc]

一、设置面试官权限

1)数据权限

  • 通过get_list_fieldsets控制admin选项option中的fieldsets 实现


预期效果


  1. hr 和超级用户 可以看到全部信息

  2. 一面面试官只能看到自己负责的一面面试信息

  3. 二面面试官只能看到自己负责二面面试信息

  4. 普通管理员(还未被指定一面或者二面面试官)只能修改候选人信息


代码实现(核心代码)


  # 定义集合的字段列表  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 和超级用户



一面面试官



二面面试官


2) 数据集的权限控制

  • 通过重写 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))
复制代码


成功实现



3) action 行为权限

在添加群组时我们为interviewer群组添加了增删改查应聘者的权限,这里再为普通面试官添加不可导出为csv action 行为 的权限以及不可删除对象delete_selected)的权限


  1. 方法一:添加权限实现(为Candidate模型Meta 为其设置自定义权限(元组))

  2. 方法二:有条件的启用或禁用行为(get_actions

  3. 方法三:全局禁用,局部使用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): ······
复制代码


官方文档modeladmin配置


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参数其实就是对应modelMeta


  • 效果


  • 现在还无法看到权限,因为model模型Meta信息还没有同步到数据库(如果数据库 auth 用户验证模块没有这个定义,这里是不显示的)


  • 数据迁移两把斧运行



成功


二、 钉钉群消息集成

1)简单 shell 测试


  • 在应用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'])
复制代码


2)在 admin 后台添加通知面试官 action

在实际中,我们希望直接通知最近需要面试候选人得面试官,所以我们为应聘者添加一个 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")) # 是否有对应权限
复制代码


  • 效果


用户头像

还未添加个人签名 2022.08.13 加入

还未添加个人简介

评论

发布
暂无评论
【Django | 开发】面试招聘信息网站(划分面试官权限&集成钉钉消息)_8月月更_计算机魔术师_InfoQ写作社区