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

Django REST Framework按外键过滤GET请求(MultipleObjectsReturned错误)

解决指定用户关联Supplier的过滤问题

错误原因

你设置了lookup_field='user',当访问/pm/getsuppliers/{user_id}/时,ModelViewSet的retrieve详情视图会自动调用Supplier.objects.get(user=user_id)查询单条记录。但一个User对应多个Supplier,get()方法要求只能返回单个对象,因此触发MultipleObjectsReturned异常。

解决方案

方案1:使用查询参数过滤列表视图

修改views.py,重写get_queryset方法,通过URL查询参数过滤指定用户的Supplier:

class getsuppliers(viewsets.ModelViewSet):
    queryset = Supplier.objects.all()
    serializer_class = GetSuppliersSerializer

    def get_queryset(self):
        # 先获取基础查询集
        queryset = super().get_queryset()
        # 从请求查询参数中获取user_id
        user_id = self.request.query_params.get('user_id')
        if user_id:
            # 过滤出该用户的所有Supplier
            queryset = queryset.filter(user_id=user_id)
        return queryset

访问方式:http://localhost:8000/pm/getsuppliers/?user_id=你的用户ID

方案2:自定义URL动作(符合REST路径风格)

如果希望用/pm/getsuppliers/user/{user_id}/这种路径访问,可通过DRF的@action装饰器添加自定义动作:

from rest_framework.decorators import action
from rest_framework.response import Response

class getsuppliers(viewsets.ModelViewSet):
    queryset = Supplier.objects.all()
    serializer_class = GetSuppliersSerializer

    @action(detail=False, url_path='user/(?P<user_id>[0-9]+)')
    def by_user(self, request, user_id=None):
        # 过滤指定用户的所有Supplier
        suppliers = Supplier.objects.filter(user_id=user_id)
        # 序列化多个对象需指定many=True
        serializer = self.get_serializer(suppliers, many=True)
        return Response(serializer.data)

访问方式:http://localhost:8000/pm/getsuppliers/user/你的用户ID/

关键说明

  • 不要用lookup_field='user'实现列表过滤:lookup_field是用于详情视图查找单条记录的字段,不适合一对多关联场景。
  • 使用filter()替代get():filter()会返回符合条件的所有对象(QuerySet),而get()仅返回单个对象,这正是批量查询需要的逻辑。

内容的提问来源于stack exchange,提问作者Kyle Andrew

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:30:50