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

Django 如何在 permissions.py 中获取 Quiz 模型的 start 参数

解决方法

你需要根据业务场景,选择两种不同的方式获取Quiz模型的start参数值:

场景1:校验单个Quiz对象的操作权限

针对查看/修改/删除指定Quiz的请求,使用DRF权限类自带的has_object_permission方法即可直接拿到目标Quiz实例,代码实现如下:

from rest_framework import permissions
from django.utils import timezone
from .models import Quiz

class IsTimeNotDefined(permissions.BasePermission) :
    def has_permission(self, request, view):
        # 非安全方法先放行,后续到对象权限层再校验时间规则
        return request.method not in permissions.SAFE_METHODS

    def has_object_permission(self, request, view, obj):
        # 此处obj就是当前请求对应的Quiz实例,直接取start属性即可
        quiz_start_time = obj.start
        # 示例逻辑:当前时间早于活动开始时间则禁止操作
        if timezone.now() < quiz_start_time:
            return False
        return True

注意:使用该方法需要确保你的视图类调用了对象权限校验逻辑,通用视图(GenericAPIView)及子类默认会自动调用。


场景2:非单个Quiz请求下获取start参数

如果是列表请求、创建关联资源请求等场景,没有自动传入的Quiz实例,你可以从URL路径参数、请求体参数中提取quiz_id,主动查询数据库获取对象:

from rest_framework import permissions
from django.utils import timezone
from .models import Quiz

class IsTimeNotDefined(permissions.BasePermission) :
    def has_permission(self, request, view):
        if request.method in permissions.SAFE_METHODS:
            return False
        # 从URL路径参数中获取quiz_id,参数名和你urls.py中定义的一致即可
        quiz_id = view.kwargs.get('quiz_id')
        # 如果是从请求体拿参数,使用request.data.get('quiz_id')即可
        if not quiz_id:
            return False
        # 查询Quiz实例
        try:
            quiz = Quiz.objects.get(id=quiz_id)
        except Quiz.DoesNotExist:
            return False
        # 获取start参数做业务校验
        quiz_start_time = quiz.start
        if timezone.now() < quiz_start_time:
            return False
        return True

注意事项

  • 时间对比请统一使用django.utils.timezone.now()获取当前时间,避免时区配置导致的判断错误。
  • 如果你的业务逻辑是校验请求关联的所有Quiz的时间,可批量查询后遍历校验即可。

内容的提问来源于stack exchange,提问作者Arslan Yersain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 09:27:05