Django自定义装饰器条件设置问题:如何添加Inspector模型的inspector_varified验证条件
搞定你的Django检查员权限装饰器
我来帮你扩展这个装饰器,满足第三个权限验证条件。你只需要在原有的user_passes_test验证逻辑里,加入对关联Inspector模型中inspector_varified字段的检查,同时还要注意避免用户没有关联Inspector实例时抛出异常,具体修改如下:
修改后的完整装饰器代码
from django.contrib.auth.decorators import user_passes_test from django.contrib.auth import REDIRECT_FIELD_NAME def inspector_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url='app2:request_login'): actual_decorator = user_passes_test( lambda u: ( u.is_active and u.is_Inspector # 先确认用户有对应的Inspector关联记录 and u.inspector_releted_user.exists() # 再检查该记录是否已通过验证 and u.inspector_releted_user.first().inspector_varified ), login_url=login_url, redirect_field_name=redirect_field_name ) if function: return actual_decorator(function) return actual_decorator
关键逻辑说明
- 保留你原来的两个验证条件:
u.is_active确保用户账号正常,u.is_Inspector确认用户身份为检查员 u.inspector_releted_user.exists():先判断当前用户是否存在关联的Inspector实例,避免因没有关联数据导致查询报错u.inspector_releted_user.first().inspector_varified:获取第一个关联的Inspector记录(如果你的业务里一个检查员用户只对应一条Inspector记录,这个逻辑完全没问题),检查其是否已通过验证
可选优化(更贴合一对一业务场景)
如果你的业务规则是每个检查员用户只会对应一条Inspector记录,我建议把models.py里的ForeignKey改成OneToOneField,这样反向关联会直接返回单个对象,代码更简洁也更合理:
第一步:修改模型关联
class Inspector(models.Model): # 把ForeignKey改为OneToOneField,同时可以更新related_name更直观 user = models.OneToOneField(myCustomeUser, on_delete=models.CASCADE, related_name='inspector_profile') name = models.CharField(max_length=200, blank=False, null=True) gmail = models.EmailField(null=True, blank=False, unique=True) nid = models.IntegerField(blank=False, unique=True) inspector_varified = models.BooleanField(default=False, blank=True, null=True) def __str__(self): return self.name
第二步:简化装饰器逻辑
def inspector_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url='app2:request_login'): actual_decorator = user_passes_test( lambda u: ( u.is_active and u.is_Inspector # 检查是否存在关联的Inspector实例,再验证状态 and hasattr(u, 'inspector_profile') and u.inspector_profile.inspector_varified ), login_url=login_url, redirect_field_name=redirect_field_name ) if function: return actual_decorator(function) return actual_decorator
这样修改后,代码逻辑更清晰,也更符合业务场景的实际情况。
内容的提问来源于stack exchange,提问作者Kanchon Gharami
相关产品推荐
相关产品推荐

