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
相关产品推荐
相关产品推荐

