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

Django使用ModelViewSet时如何获取PATCH请求URL中的id参数?

你在initialize_request中无法正确获取id的核心原因是:DRF的路由参数解析流程晚于initialize_request的执行,在该方法执行时self.kwargs还没有被赋值,你调用MyModel.objects.get()时没有传入过滤条件,才会返回多个对象报错。

可选解决方案

方法1:在initialize_request中手动解析请求路径

如果必须在initialize_request阶段获取id,可以通过正则匹配请求路径提取目标值:

import re
from rest_framework.viewsets import ModelViewSet
from .models import MyModel
from .serializers import MyModelSerializer

class MyModelViewSet(ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

    def initialize_request(self, request, *args, **kwargs):
        # 先执行父类逻辑拿到标准request对象
        request = super().initialize_request(request, *args, **kwargs)
        # 正则匹配路径中的id值,规则可根据你的实际路由调整
        path = request.path_info
        id_match = re.search(r'/api/details/(\d+)/', path)
        if id_match:
            target_id = int(id_match.group(1))
            # 此时就可以用过滤条件查询单条对象
            target_instance = MyModel.objects.get(id=target_id)
            # 执行你需要的业务逻辑
        return request

方法2:更换到后续生命周期钩子获取(更推荐)

如果没有强需求必须在initialize_request中处理,更建议在路由参数解析完成后的钩子中操作,不需要手动解析路径:

class MyModelViewSet(ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MyModelSerializer

    def get_object(self):
        # 路由解析完成后可以直接从kwargs中拿主键,参数名和路由定义保持一致即可
        target_id = self.kwargs.get('pk')
        target_instance = MyModel.objects.get(id=target_id)
        # 执行你需要的业务逻辑
        return super().get_object()

注意事项

  • 如果自定义路由的主键参数名不是pk,把self.kwargs.get('pk')的key替换为你实际定义的参数名即可
  • 手动解析路径时正则规则需要和你的路由配置完全匹配,避免匹配到错误数值

内容的提问来源于stack exchange,提问作者Anirban Nag 'tintinmj'

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 07:48:02