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
相关产品推荐
相关产品推荐

