【问题标题】:Render one queryset into 2 div columns (django template)将一个查询集渲染为 2 个 div 列(django 模板)
【发布时间】:2010-12-09 06:31:56
【问题描述】:

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

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

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

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

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

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

views.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>

【问题讨论】:

    标签: django django-templates 960.gs


    【解决方案1】:

    我推荐使用Django filters

    Django sn-ps 提供了一个partitioning template filter,你可以像这样使用它:

    {% 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>
    

    【讨论】:

    • 聪明的过滤器!这是我想去的方向。
    【解决方案2】:

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

    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)
    

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

    【讨论】:

      【解决方案3】:

      这是一个使用引导程序且不需要 Django 过滤器的快速解决方案

      <div class="row">
          {% for sport in sports %}
              <div class="col-md-6">
                  <!-- Blah Blah -->
              </div>
          {% endfor %}
      </div>
      

      【讨论】:

      • 这不是他想要的。他想要一列中的一些项目,而另一列中的其余项目。您的灵魂将把每个项目放在一个列中。
      【解决方案4】:
      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”的问题

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-06
        • 1970-01-01
        • 1970-01-01
        • 2023-04-09
        • 2012-10-27
        • 2023-04-09
        • 1970-01-01
        • 2014-03-15
        相关资源
        最近更新 更多