Pergunta

Existe uma boa maneira de renderizar a enumeração de um conjunto de consultas em dois div colunas?

Usando 960 grade, eu tenho algo com o efeito de ...

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

Em Django, um modelo precisa ter seu conteúdo enumerado renderizado em ambas as colunas e, de preferência, de alguma forma igualmente. No momento, eu tenho algum código feio que, na visualização, divide a consulta em 2 metades e, em seguida, cada metade é renderizada em sua respectiva coluna.

Deve haver uma maneira melhor de fazer isso, de preferência usando apenas o sistema de renderização do modelo?

Apenas para referência, eis como "funciona" no momento:

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:] }

template.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>
Foi útil?

Solução

Eu recomendo usar Filtros de Django.

Os trechos de django fornecem um filtro de modelo de partição, que você pode usar como:

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

Outras dicas

  1. Esta é a tarefa de um sistema de renderização, não de visualização. A visualização não deve saber se você exibirá 2, 3 ou 4 colunas em seu modelo.
  2. É sempre melhor usar tags de django padrão.

Use a tag de modelo de django padrão 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>

Ele exibirá sua lista [1 2 3 4 5 6] como

1 2

3 4

5 6

A propósito, o mecanismo de modelo Jinja2 tem batch e slice filtros que farão o truque. Mudei para o Jinja2 e agora não tenho nenhum desses problemas de "Como exibir x usando tags e filtros pobres do django"

Eu acho que você terá que fazer sua própria tag de modelo para fazer divisões em consultas. Eu faria algo como.

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)

Observe que eu não testei esse código, por isso pode falhar espetacularmente, mas deve apontar para a direção certa para tirar essas coisas da sua opinião.

Aqui está uma solução rápida que usa o bootstrap e não precisa de filtros de django

<div class="row">
    {% for sport in sports %}
        <div class="col-md-6">
            <!-- Blah Blah -->
        </div>
    {% endfor %}
</div>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top