Django中按数据库列值分类数据并实现表格无空白单元格展示的问题
看起来你现在遇到的问题是,想要把数据库里的两类疾病数据分别放在表格的两列中,结果却出现了大量空白单元格,对吧?我来帮你分析一下问题所在,然后给出解决方案。
先理清楚你的现有实现和问题
你现在的代码逻辑是把所有数据都传给模板,然后在模板里每循环一条数据就生成一行,每行里两个<td>分别判断分类来显示内容。但这样做的问题是:每条数据只属于其中一类,所以每一行必然只有一个单元格有值,另一个是空的,这就是你看到大量空白的原因。
你的现有代码
模板文件(hasil-cluster.html)
<tbody> <tr class=""> {% for c in cluster %} <td>{% if c.hasil_klasifikasi == 'Banyak Terjangkit' %}{{ c.nama_penyakit }}{% endif %}</td> <td>{% if c.hasil_klasifikasi == 'Kurang Terjangkit' %}{{ c.nama_penyakit }}{% endif %}</td> </tr> {% endfor %} </tbody>
视图文件(views.py)
cluster = tb_hasil_cluster.objects.all() context = {'chart':chart,'cluster':cluster} return render(request, 'hasil-cluster.html', context)
问题现象
你现在的表格会变成这样:每一行要么左列有值、右列空白,要么右列有值、左列空白,完全不符合你想要的“两列分别对应两类数据,无空白”的效果。
解决方案:先分组再渲染
正确的思路应该是先把数据按分类分成两组,然后把两组数据配对后再渲染到表格中,这样每一行的两个单元格就能对应两类的数据,不会出现空白。我推荐在视图层处理数据分组,因为模板的职责应该是展示数据,而不是处理数据逻辑。
步骤1:修改views.py,拆分并配对数据
在视图里把两类数据分别查询出来,然后用zip_longest把它们配对(如果某类数据更多,会自动补空):
from django.shortcuts import render from .models import tb_hasil_cluster # 导入zip_longest来处理两组数据长度不一致的情况 from itertools import zip_longest def hasil_cluster_view(request): # 分别查询两类分类的数据 banyak_group = tb_hasil_cluster.objects.filter(hasil_klasifikasi='Banyak Terjangkit') kurang_group = tb_hasil_cluster.objects.filter(hasil_klasifikasi='Kurang Terjangkit') # 把两组数据配对,长度不足的用None补全 paired_data = zip_longest(banyak_group, kurang_group, fillvalue=None) context = { 'chart': chart, 'paired_data': paired_data # 把配对好的数据传给模板 } return render(request, 'hasil-cluster.html', context)
步骤2:修改模板,渲染配对后的数据
现在模板只需要循环配对好的数据,每一行的两个单元格分别对应两类的疾病名称即可:
<tbody> {% for banyak_item, kurang_item in paired_data %} <tr> <!-- 显示Banyak Terjangkit的疾病,没有的话显示空字符串 --> <td>{{ banyak_item.nama_penyakit if banyak_item else '' }}</td> <!-- 显示Kurang Terjangkit的疾病,没有的话显示空字符串 --> <td>{{ kurang_item.nama_penyakit if kurang_item else '' }}</td> </tr> {% endfor %} </tbody>
为什么这个方案能解决问题?
这样处理后,我们把所有“Banyak Terjangkit”的疾病放在一组,“Kurang Terjangkit”的放在另一组,然后把两组的第1条、第2条...依次配对成一行,这样每一行的两个单元格都会对应各自分类的疾病(如果某类数据数量少,后面的行对应单元格就显示空,而不是像之前那样每行都有空白),完全符合你想要的效果。
额外说明
如果你的两类数据数量完全一致,用普通的zip()也可以,但zip_longest能兼容数量不一致的情况,更稳妥。
备注:内容来源于stack exchange,提问作者Yahya As-Shiddiq

