如何在Django中将Queryset渲染为表格模板

8 投票
3 回答
31505 浏览
提问于 2025-04-17 12:39

我有一个模型,定义如下,它会根据查询获取一系列对象,然后把这些对象放到表格的合适单元格里。下面是相关的代码部分。

class Location(models.Model):
    x=models.IntegerField(null=True)
    y=models.IntegerField(null=True)
    z=models.CharField(max_length=5,null=True)

    def __unicode__(self):
        return self.z

我想从这个数据库中提取所有对象,并把它们放到一个二维表格中,表格的行和列由对象的 x 和 y 值决定。如果某个 (x,y) 没有对象,那么这个位置在表格中就应该显示为空。这是我为实现这个目标写的视图。

def gettable(request):
    events=[]
    for xdim in xrange(3):
        xe=[]
        for ydim in xrange(3):
            object=[0]
            object.append(Location.objects.filter(x=xdim,y=ydim))
            xe.append(object[-1])
            events.append(xe)
    return render(request, 'scheduler/table.html', {'events':events})

下面是代码的 HTML 部分。

<table border="1">
    <th>Header 0</th>
    <th>Header 1</th>
    <th>Header 2</th>
    {% for event in events %}
    <tr>
    {% for x in event %} <td>{{ x }}</td>
    {% endfor %}
    </tr>
    {% endfor %}
</table>

我在这里需要解决几个问题。

1. 我的视图代码看起来一点也不优雅(这很糟糕,因为我知道 Django 提供了很多工具来处理这样的任务),因为我专门定义了变量来循环,而不是直接使用数据库对象的 (x,y) 值。

2. 我得到的输出是 [<Location: 21>] 这种格式,但我想要的是 '21'。

3. 我该如何在没有对象的 (x,y) 位置引入空单元格。

4. 请建议其他可能的方法,让我的代码更简单和通用。

3 个回答

1

逐条解释:

  1. 我觉得你可以创建一个自定义的过滤器或者标签,然后使用查询集。
  2. 你需要定义一个 __unicode__(或者 __string__)的方法来返回你想要的内容。
  3. 如果值是空的或者这个项目不存在,最终显示的结果也会是空的。

希望这对你有帮助!

1

关于第二点,你给每个单元格的是一个列表,而不是一个单独的对象。{{ x.0 }} 应该能给你正确的值,但这也说明你的视图逻辑可能有点问题。

23

如果你想让你的代码更简单,我推荐你使用一个叫做 django-tables2 的工具。这个工具可以解决你在生成表格时遇到的所有问题。

根据文档的介绍:

django-tables2 让把数据变成 HTML 表格的工作变得简单。它支持分页和排序功能。它的作用就像 django.forms 对 HTML 表单的作用一样。例如:

它的特点包括:

  • 任何可以迭代的数据都可以作为数据源,但特别支持 Django 的查询集。
  • 内置的用户界面不依赖 JavaScript。
  • 支持根据 Django 模型自动生成表格。
  • 通过子类化支持自定义列功能。
  • 分页功能。
  • 基于列的表格排序。
  • 提供模板标签,可以轻松渲染成 HTML。
  • 适用于 Django 1.3 的通用视图混合。

创建一个表格非常简单:

import django_tables2 as tables

class SimpleTable(tables.Table):
    class Meta:
        model = Simple 

然后可以在视图中使用:

def simple_list(request):
    queryset = Simple.objects.all()
    table = SimpleTable(queryset)
    return render_to_response("simple_list.html", {"table": table},
                              context_instance=RequestContext(request))

最后在模板中使用:

{% load django_tables2 %} 
{% render_table table %}

这个例子展示了最简单的用法,但 django-tables2 还能做更多的事情!想了解更多细节,可以查看 文档

你也可以使用字典而不是查询集。

撰写回答