You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 03:37:48