如何在Django中仅获取多关联模型的最新数据行并以表格形式展示且避免重复数据
解决Django库存展示重复数据并仅显示最新行的问题
首先,咱们先拆解下你当前代码的问题:你在视图里只取了第一个供应商产品的变体列表,但模板里却嵌套循环了所有供应商产品和这个变体列表,这就导致每个产品都会重复展示同一组变体数据,自然出现了重复。接下来根据你的需求分两种场景给出解决方案:
场景1:仅展示全局最新添加的一条库存数据
如果你的需求是每次只展示整个供应商库存中最新添加的那一行变体数据,可以这样修改:
1. 更新 views.py
from django.shortcuts import render from .models import CustomUser, ProductVariants def inventory_display(request): # 验证供应商身份 if request.user.vendor and request.user.vendor_approval: # 筛选当前供应商的所有变体,按创建时间倒序排序,取第一条(最新的) latest_item = ProductVariants.objects.filter( product__vendoruser=request.user ).order_by('-created').first() # 假设你的ProductVariants模型有`created`时间字段,没有的话替换成你实际的新增时间字段 context = {} if latest_item: # 关联对应的产品信息 context['latest_item'] = latest_item context['vendor_product'] = latest_item.product return render(request, 'vendor/inventory_display.html', context)
2. 更新HTML模板
现在不需要嵌套循环了,直接渲染单条数据即可:
{% if latest_item and vendor_product %} <tr> <th scope="row">1</th> <td>{{vendor_product.created|date:"d-m-y"}}</td> <td>{{vendor_product.edited|date:"d-m-y"}}</td> <td>{{vendor_product.vendoruser}}</td> <!-- 注意:这里需要给URL传递product_id参数,否则会报错 --> <td><a href="{% url 'loomerang_admin:product_details' vendor_product.product_id %}">{{vendor_product.product_id}}</a></td> <td>{{latest_item.item_num}}</td> <td>{{latest_item.variant_value}}</td> <td>{{latest_item.initial_stock}}</td> <td>2</td> <!-- 这里的固定值"2"建议替换成动态字段,比如latest_item.current_stock --> <td>{{latest_item.approval_status}}</td> <td>{{latest_item.approved_date|date:"d-m-y"}}</td> <td>{{vendor_product.approved_by}}</td> </tr> {% else %} <tr> <td colspan="12">暂无最新库存数据</td> </tr> {% endif %}
场景2:展示每个产品的最新一条变体数据
如果你的需求是每个产品只显示它最新添加的那一行变体数据,可以用以下方案:
1. 更新 views.py
from django.shortcuts import render from django.db.models import Max from django.db.models import Prefetch from .models import Product, ProductVariants def inventory_display(request): if request.user.vendor and request.user.vendor_approval: # 获取当前供应商的所有产品,预取每个产品的最新变体 vendor_products = Product.objects.filter( vendoruser=request.user ).annotate( # 标记每个产品的最新变体创建时间 latest_variant_created=Max('product_variants__created') ).prefetch_related( # 预取每个产品的变体,按创建时间倒序,方便取第一条 Prefetch( 'product_variants', queryset=ProductVariants.objects.order_by('-created'), to_attr='latest_variants' ) ) # 整理成产品+对应最新变体的列表 product_latest_variant = [] for product in vendor_products: if product.latest_variants: product_latest_variant.append({ 'product': product, 'latest_item': product.latest_variants[0] }) return render(request, 'vendor/inventory_display.html', { 'product_latest_variant': product_latest_variant })
2. 更新HTML模板
现在只需要一层循环就能展示每个产品的最新变体,不会重复:
{% for entry in product_latest_variant %} <tr> <th scope="row">{{forloop.counter}}</th> <td>{{entry.product.created|date:"d-m-y"}}</td> <td>{{entry.product.edited|date:"d-m-y"}}</td> <td>{{entry.product.vendoruser}}</td> <td><a href="{% url 'loomerang_admin:product_details' entry.product.product_id %}">{{entry.product.product_id}}</a></td> <td>{{entry.latest_item.item_num}}</td> <td>{{entry.latest_item.variant_value}}</td> <td>{{entry.latest_item.initial_stock}}</td> <td>2</td> <!-- 替换为动态字段 --> <td>{{entry.latest_item.approval_status}}</td> <td>{{entry.latest_item.approved_date|date:"d-m-y"}}</td> <td>{{entry.product.approved_by}}</td> </tr> {% empty %} <tr> <td colspan="12">暂无库存数据</td> </tr> {% endfor %}
关键注意点
- 确保你的
ProductVariants模型有用于排序的时间字段(比如created或added_date),如果没有的话需要先添加。 - 原模板中的
{% url 'loomerang_admin:product_details' %}缺少必要的参数,需要补充product_id,否则会抛出URL匹配错误。
内容的提问来源于stack exchange,提问作者user17408361
相关产品推荐
相关产品推荐

