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

Django返回404错误:未找到匹配的Order Item请求助排查

为什么Django返回"Page not found (404) No order item matching the query"错误?

错误信息

"Page not found (404) No order item matching the query"

问题核心

你的OrderDetail视图继承自DetailView且指定了model = Order,但重写的get_queryset方法返回的是OrderItem的查询集合,这直接造成逻辑冲突:

  • DetailView的设计目标是展示单个模型对象,这里指定的是Order模型,原本会根据order_id去Order表中匹配对应订单。
  • 但你返回的OrderItem查询集,会让Django尝试用传入的order_id去匹配OrderItem的主键ID,而非Order的ID,自然找不到对应数据,触发404错误。

你打印的queryset显示存在符合条件的OrderItem,但这和DetailView需要的单个Order对象没有关联。

相关代码展示

视图代码

class OrderDetail(DataMixin, DetailView):
    model = Order
    template_name = 'orders/order_detail.html'
    context_object_name = 'order'
    pk_url_kwarg = 'order_id'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        c_def = self.get_user_context()
        return context | c_def | {'title': 'Заказ'}

    def get_queryset(self):
        queryset = OrderItem.objects.filter(order_id=self.kwargs['order_id'])
        return queryset

主URL配置

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('home.urls', namespace='home')),
    path('cart/', include('cart.urls', namespace='cart')),
    path('orders/', include('orders.urls', namespace='orders')),
    path('users/', include('users.urls', namespace='users')),
]

orders应用URL配置

app_name = 'orders'

urlpatterns = [
    path('order/<int:order_id>/', OrderDetail.as_view(), name='order_detail'),
    path('create/', OrderCreateView.as_view(), name='order_create'),
]

模型定义

class Order(models.Model):
    username = models.CharField(max_length=100, verbose_name='Логин')
    first_name = models.CharField(max_length=50, verbose_name='Имя')
    last_name = models.CharField(max_length=50, verbose_name='Фамилия')
    email = models.EmailField()
    address = models.CharField(max_length=250, verbose_name='Адрес')
    postal_code = models.CharField(max_length=20, verbose_name='Почтовый индекс')
    city = models.CharField(max_length=100, verbose_name='Город')
    created = models.DateTimeField(auto_now_add=True, verbose_name='Создан')
    updated = models.DateTimeField(auto_now=True, verbose_name='Обновлен')
    paid = models.BooleanField(default=False, verbose_name='Оформлен')

    class Meta:
        ordering = ('-created',)
        verbose_name = 'Заказ'
        verbose_name_plural = 'Заказы'

    def __str__(self):
        return f'Order {self.id}'

    def get_total_cost(self):
        total_cost = self.items.aggregate(total_cost=Sum('price'))['total_cost']
        return total_cost or 0


class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
    product = models.ForeignKey(Product, related_name='order_items', on_delete=models.CASCADE)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.PositiveIntegerField(default=1)

    def __str__(self):
        return f'{self.id}'

    def get_cost(self):
        return self.price * self.quantity

模板代码

<a class="link-secondary" href="{% url 'orders:order_detail' order_id %}">Изменить</a>

解决方法

  1. 删除错误的get_queryset重写方法:
    OrderDetail是用来展示单个Order对象的,无需返回OrderItem查询集,直接让DetailView默认根据order_id去Order表中查找对象即可。

  2. 在模板中访问订单对应的商品项:
    由于Order和OrderItem通过外键关联且设置了related_name='items',可在模板中直接通过{{ order.items.all }}获取该订单下的所有OrderItem。

修改后的视图代码:

class OrderDetail(DataMixin, DetailView):
    model = Order
    template_name = 'orders/order_detail.html'
    context_object_name = 'order'
    pk_url_kwarg = 'order_id'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        c_def = self.get_user_context()
        # 若需提前将OrderItem放入上下文,可添加此行
        # context['order_items'] = self.object.items.all()
        return context | c_def | {'title': 'Заказ'}

修改后Django会正确根据order_id找到对应的Order对象,同时你可在模板中轻松获取该订单下的所有商品项,不会再触发404错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:54:54