17

有没有一种好方法可以将查询集的枚举呈现为两div列?

使用 960 网格,我有一些效果...

<div class="container_16">
    <div class="grid_8 alpha"></div>
    <div class="grid_8 omega"></div>
</div>

在 Django 中,一个模型需要在这两个列中呈现它的枚举内容,并且最好在某种程度上相等。目前,我有一些丑陋的代码,在视图中将 QuerySet 分成两半,然后每一半在各自的列中呈现。

必须有更好的方法来做到这一点,最好只使用模板渲染系统?

仅供参考,以下是它目前“工作”的方式:

视图.py

@render_to('template.html')
def main_athletics_page(request, *args, **kwargs):    
    sports = Sport.objects.all()
    half = sports.count() / 2
    return { 'sports_1' : sports[0:half], 'sports_2' : sports[half:] }

模板.html

<div class="grid_8 alpha">
    {% for sport in sports_1 %}
        <!-- Blah blah -->
    {% endfor %}
</div>

<div class="grid_8 omega">
    {% for sport in sports_2 %}
        <!-- Blah blah -->
    {% endfor %}
</div>
4

4 回答 4

16

我推荐使用Django 过滤器

Django 片段提供了一个分区模板过滤器,你可以像这样使用它:

{% load listutil %}

<div class="grid_8 alpha">
    {% for sport in sports|partition:"2"|first %}
        <!-- Blah Blah -->
    {% endfor %}
</div>

<div class="grid_8 omega">
    {% for sport in sports|partition:"2"|last %}
        <!-- Blah Blah -->
    {% endfor %}
</div>
于 2009-10-22T22:24:31.227 回答
6
  1. 这是渲染系统的任务,而不是视图。视图不应该知道您将在模板中显示 2、3 还是 4 列。
  2. 使用默认的 Django 标签总是更好。

使用默认的 Django 模板标签cycle

<table>
    {% for item in items %}
        {% cycle 'row' '' as row silent %}
        {% if row %}<tr>{% endif %}
            <td>
                {{ item }}
            </td>
        {% if not row %}</tr>{% endif %}
    {% endfor %}
</table>

它会将您的列表 [1 2 3 4 5 6] 显示为

1 2

3 4

5 6

顺便说一句,Jinja2 模板引擎有batchslice过滤器可以解决问题。我切换到 jinja2,现在没有“如何使用糟糕的 django 标签和过滤器显示 x”的问题

于 2014-10-13T06:38:35.353 回答
1

我认为您必须制作自己的模板标签才能对查询进行拆分。我会做类似的事情。

from django.template import Library, Node, TemplateSyntaxError
from restaurants.forms import MenuItemForm

class Split(Node):
    def __init__(self, queryset, split_count=2, basename=None):
        self.queryset_name = queryset
        self.split_count = split_count
        self.basename = basename if basename else queryset

    def render(self, context):
        qs = context[self.queryset_name]
        qs_break = len(qs)/self.split_count
        for x in xrange(0, self.split_count-1):
            context["%s_%i"%(self.basename, x+1)] = qs[qs_break*x:qs_break*(x+1)]
        context["%s_%i"%(self.basename, x+2)] = qs[qs_break*x+1:]
        return ''        



def split(parser, token):
    """
    Call from template will be
    {% split <queryset> on <count> as <name> %}
    """
    tokens = token.split_contents()
    if len(tokens) > 6:
        raise TemplateSyntaxError("Too many Tokens")
    #Do various tests to make sure it's right.
    return Split(tokens[1], tokens[3], tokens[5])

split = register.tag(split)

请注意,我还没有实际测试过这段代码,所以它可能会失败,但它应该为你指明正确的方向,让这些东西脱离你的视野。

于 2009-10-22T22:25:03.943 回答
-1

Here's a quick solution which uses bootstrap and needs no Django filters

<div class="row">
    {% for sport in sports %}
        <div class="col-md-6">
            <!-- Blah Blah -->
        </div>
    {% endfor %}
</div>
于 2014-04-25T19:21:39.850 回答