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

Django实现三张外键关联表数据的前端表格展示

问题排查
  • 模板变量拼写错误:视图传入的资源列表变量为recursolist,模板循环时写为recursolis,变量名不匹配导致资源无法渲染
  • 查询逻辑低效:全表查询所有出库单明细后在模板层逐条匹配所属出库单,数据量稍大就会产生海量重复数据库查询,页面加载速度极慢
  • 模型语法错误:detalle_remito类的__str__方法缩进错误,定义在类外部会直接引发代码运行报错
  • 未使用Django ORM自带的外键反向关联能力,关联数据不需要单独全表查询传入模板
修正方案

1. 修复Models.py语法问题

调整detalle_remito类的方法缩进,同时给指向remito的外键增加可读性更好的反向关联名,修正后代码:

class recursos(models.Model):
    gruporecurso= models.CharField(max_length=50, choices=TIPORECURSO, default=TIPODEFAULT)
    descripcion = models.CharField(max_length=100)
    estado_disponible =models.BooleanField(default=True)
    inventario = models.CharField(max_length=40, blank=True, null=True)
    observacion = models.TextField(blank=True, null=True)

    def __str__(self):
        return self.descripcion
    
class remito(models.Model):
    fecha = models.DateField()
    hora = models.TimeField()
    responsable = models.ForeignKey(personas, null=True, blank=True, verbose_name='Responsable',on_delete=models.CASCADE)
    area_pedido = models.CharField(max_length=20, verbose_name='Área del pedido')
    operador = models.CharField(max_length=40, choices=OPERADOR,verbose_name='Entregado por')
    lugardeuso = models.CharField(max_length=40,verbose_name='Lugar uso')
    observacion = models.TextField(blank=True, null=True)

class detalle_remito(models.Model):
    id_remito = models.ForeignKey(remito, null=True, blank=False, on_delete=models.CASCADE, related_name='detalles')
    id_recurso = models.ForeignKey(recursos, null=True, blank=False, on_delete=models.CASCADE)
    cantidad = models.IntegerField(default=1)

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

外键增加related_name='detalles'参数后,可以直接通过单个remito对象.detalles拿到该出库单对应的所有明细条目,无需额外查询过滤

2. 优化Views.py查询逻辑

使用prefetch_related预加载关联的明细、明细绑定的资源数据,一次性把需要的数据查出来,避免循环查询数据库,同时去掉冗余的全量明细查询,修正后代码:

from django.core.paginator import Paginator
from django.http import Http404
from .models import remito

def home(request):
    # 预加载两层关联数据:出库单关联的明细、明细关联的资源信息
    remitos = remito.objects.all().prefetch_related('detalles__id_recurso')
    page = request.GET.get('page', 1)
    try:
        paginator = Paginator(remitos, 5)
        remitos = paginator.page(page)
    except:
        raise Http404

    return render(request, "RemitoTicapp/home.html", {'entity': remitos, 'paginator': paginator})

3. 调整home.html模板渲染逻辑

直接通过反向关联读取当前出库单对应的明细,不需要额外判断id匹配,修正后表格主体部分代码如下:

<tbody>
    {% for remito in entity %}
        <tr>
            <td scope="row">{{ remito.fecha }}</td>
            <td>{{ remito.responsable }}</td>
            <td>{{ remito.area_pedido }}</td>
            <td>{{ remito.lugardeuso }}</td>
            <td>
                <ul class="list-unstyled mb-0">
                {% for detalle in remito.detalles.all %}
                    <li>{{ detalle.id_recurso.descripcion }} × {{ detalle.cantidad }}</li>
                {% endfor %}
                </ul>
            </td>
            <td>{{ remito.operador }}</td>
            <td>{{ remito.observacion }}</td>
        </tr>
    {% endfor %}
</tbody>

列表添加Bootstrap自带的list-unstyled类,去除默认列表的缩进和项目符号,和表格样式适配更美观

内容的提问来源于stack exchange,提问作者Maria Laura Lopez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:45:35