Django Filter过滤订单后模板展示所有店铺OrderItem问题求助
问题根因
你在视图层仅对Order对象做了过滤,筛选出了包含当前店铺商品的订单,但没有对订单关联的OrderItem做范围限制。当你在模板中调用order.items.all时,Django会直接取出该订单下关联的所有商品,自然会展示其他店铺的商品。
最优解决方案(避免N+1查询,性能最优)
在视图层使用Prefetch自定义关联查询的过滤规则,一次性完成数据查询和过滤,不会产生额外的数据库请求。
首先导入依赖:
from django.db.models import Prefetch
修改视图代码:
def shop_orders(request): current_shop = request.user.user_profile_shop # 过滤出包含当前店铺商品的订单,同时预加载该订单下仅属于当前店铺的商品 orders = Order.objects.filter(items__shop=current_shop).distinct().prefetch_related( Prefetch( 'items', queryset=OrderItem.objects.filter(shop=current_shop), to_attr='current_shop_items' ) ) return render(request, 'account/paneli/shop/orders/shop_orders.html', {'orders': orders,})
修改模板遍历逻辑:
{% for order in orders %} {{ order.id }} {% for item in order.current_shop_items %} {{ item.product }} {% endfor %} {% endfor %}
说明:这里加distinct()是为了避免跨关联表过滤导致的重复Order对象返回,to_attr指定的字段会存储预过滤好的当前店铺商品列表,直接遍历即可。
其他可选方案(不推荐,仅做参考)
模板层直接加判断过滤,性能差,会产生N+1查询,每遍历一个订单就会触发一次数据库查询:
{% for item in order.items.all %} {% if item.shop == request.user.user_profile_shop %} {{ item.product }} {% endif %} {% endfor %}
内容的提问来源于stack exchange,提问作者Guiana Annimali
相关产品推荐
相关产品推荐

