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

Django REST Framework ValueError:按登录用户筛选订单报错解决

问题:按客户ID筛选订单触发ValueError错误

错误回溯信息

Traceback (most recent call last):
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
    return view_func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/rest_framework/viewsets.py", line 124, in view
    return self.dispatch(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/rest_framework/mixins.py", line 38, in list
    queryset = self.filter_queryset(self.get_queryset())
                                    ^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/econ/AdnexumActio/views.py", line 264, in get_queryset
    return Order.objects.filter(customer_id=customer_id)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/query.py", line 1476, in filter
    return self._filter_or_exclude(False, args, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/query.py", line 1494, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, args, kwargs)
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/query.py", line 1501, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1613, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1645, in _add_q
    child_clause, needed_inner = self.build_filter(
                                 ^^^^^^^^^^^^^^^^^^
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1532, in build_filter
    self.check_related_objects(join_info.final_field, value, join_info.opts)
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1346, in check_related_objects
    self.check_query_object_type(value, opts, field)
  File "/home/mango/Desktop/blessings/env/lib/python3.11/site-packages/django/db/models/sql/query.py", line 1323, in check_query_object_type
    raise ValueError(
ValueError: Cannot query "John Smith": Must be "User" instance.
[22/Jun/2024 15:14:00] "GET /orders/ HTTP/1.1" 500 146350

相关代码片段

views.py

class OrderViewSet(ModelViewSet):
    permission_classes = [IsAuthenticated]


    def get_serializer_class(self):
        if self.request.method == 'POST':
            return CreateOrderSerializer
        return OrderSerializer
    

    def get_serializer_context(self, *args, **kwargs):
        return {'user_id': self.request.user.id}


    def get_queryset(self):
        # user  = self.request.user
        user = self.request.user
        # print(f"User object: {user}, type: {type(user)}")
        
        if user.is_staff:
            return Order.objects.all()
        
        
        customer_id = Customer.objects.only('id').get(user_id=user.id)
        return Order.objects.filter(customer_id=customer_id)

models.py

from django.db import models
from django.conf import settings

class Customer(models.Model):
    phone = models.CharField(max_length=255)
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

class Order(models.Model):
    placed_at = models.DateTimeField(auto_now_add=True)
    payment_status = models.CharField(max_length=1, choices=[('P', 'Pending'), ('C', 'Complete'), ('F', 'Failed')], default='P')
    customer = models.ForeignKey(Customer, on_delete=models.PROTECT)
    tickets = models.ManyToManyField('Ticket', through='OrderItem')

问题分析与解决方案

问题原因

错误核心在于get_queryset方法的变量混淆:

  • customer_id = Customer.objects.only('id').get(user_id=user.id)返回的是Customer对象,不是数值类型的ID,但变量名取成了customer_id,造成误解。
  • 后续调用Order.objects.filter(customer_id=customer_id)时,Django将customer_id识别为外键关联字段,期望传入Customer实例或对应ID数值,但实际传入的是Customer对象,导致逻辑混淆,触发类型错误。

修复方法

有两种简洁有效的修复方式:

方式一:获取Customer的ID数值

修改get_queryset方法,明确取出Customer对象的id属性:

def get_queryset(self):
    user = self.request.user
    if user.is_staff:
        return Order.objects.all()
    
    customer = Customer.objects.only('id').get(user_id=user.id)
    return Order.objects.filter(customer_id=customer.id)

方式二:直接通过关联关系筛选(更高效)

利用Django ORM的关联查询能力,无需单独查询Customer,一次数据库查询即可完成:

def get_queryset(self):
    user = self.request.user
    if user.is_staff:
        return Order.objects.all()
    
    return Order.objects.filter(customer__user=user)

内容的提问来源于stack exchange,提问作者Sean Oduor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 05:27:02