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

Django查询PostgreSQL返回数组数据如何拆分渲染到HTML表格

解决方案

核心问题为你当前的模型将同一张发票下的多个商品的名称、单价、数量都以字符串形式的数组字面量存在同一行字段中,且模板仅遍历发票行对象,没有拆分每个商品条目,因此会直接输出整个数组字符串。


方案一:快速兼容方案(无需修改现有表结构和存量数据)

1. 修改视图代码,解析字符串数组并配对商品

使用ast.literal_eval安全解析字符串格式的数组为Python列表,再通过zip方法将三个数组的同位置元素配对为单个商品条目:

import ast
from django.shortcuts import render
from .models import PurchaseInvoice

def purchaseDetails(request,pk):
    # 取对应发票数据
    invo_data = PurchaseInvoice.objects.filter(invoice=pk).first()
    # 解析字符串为列表
    product_names = ast.literal_eval(invo_data.product_name)
    prices = ast.literal_eval(invo_data.price)
    quantities = ast.literal_eval(invo_data.quantity)
    # 配对生成商品列表
    product_list = [
        {"name": name, "price": price, "quantity": qty, "amount": float(price)*int(qty)}
        for name, price, qty in zip(product_names, prices, quantities)
    ]
    return render(request,'purchase/invoice_details.html',{
        'invoice': invo_data,
        'product_list': product_list
    })

2. 修改HTML模板代码,遍历商品列表渲染表格

直接遍历生成好的商品列表,每个商品对应一行:

{% for product in product_list %}
<tr>
    <td>{{ product.name }}</td>
    <td>{{ product.price }}</td>
    <td>{{ product.quantity }}</td>
    <td>{{ product.amount }}</td>
</tr>
{% endfor %}

方案二:规范优化方案(长期使用推荐,符合数据库设计范式)

现有表结构不符合数据库第一范式,存在多字段数组长度不匹配、无法单独查询/修改单个商品、数值计算效率低等问题,推荐拆分为发票主表和商品明细表:

1. 调整模型定义

from django.db import models
from datetime import date

# 发票主表,存发票公共信息
class PurchaseInvoice(models.Model):
    id = models.AutoField(primary_key=True)
    vendor = models.CharField(max_length=50)
    invoice = models.CharField(max_length=20)
    date = models.DateField(default=date.today)

    def __str__(self):
        return self.invoice

# 商品明细表,存单个商品信息,和发票主表一对多关联
class PurchaseInvoiceItem(models.Model):
    invoice = models.ForeignKey(PurchaseInvoice, on_delete=models.CASCADE, related_name="items")
    product_name = models.CharField(max_length=500)
    # 用数值类型存价格、数量,避免字符串转义问题
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.IntegerField()

    @property
    def amount(self):
        return self.price * self.quantity

调整模型后执行makemigrations和migrate同步数据库,将存量数据拆分写入明细表即可。

2. 修改视图代码

def purchaseDetails(request,pk):
    # 预加载关联的商品明细,避免N+1查询
    invo_data = PurchaseInvoice.objects.filter(invoice=pk).prefetch_related("items").first()
    return render(request,'purchase/invoice_details.html',{'invoice': invo_data})

3. 修改HTML模板代码

{% for item in invoice.items.all %}
<tr>
    <td>{{ item.product_name }}</td>
    <td>{{ item.price }}</td>
    <td>{{ item.quantity }}</td>
    <td>{{ item.amount }}</td>
</tr>
{% endfor %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:27:01