Pregunta

¿Hay una buena manera de representar la enumeración de un queryset en dos columnas div ?

Usando la cuadrícula 960, tengo algo en el efecto de ...

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

En Django, un modelo debe tener sus contenidos enumerados representados en ambas columnas, y preferiblemente de forma un tanto equitativa. Por el momento, tengo un código feo que en la vista divide el QuerySet en 2 mitades, y luego cada mitad se representa en su columna respectiva.

Tiene que haber una mejor manera de hacerlo, preferiblemente utilizando solo el sistema de procesamiento de plantillas.

Solo como referencia, aquí está cómo " funciona " en este 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>
¿Fue útil?

Solución

Recomiendo usar filtros Django .

Los fragmentos de Django proporcionan un filtro de plantillas de partición , que puede 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>

Otros consejos

  1. Esta es la tarea de un sistema de renderizado, no de vista. La vista no debe saber si mostrará 2, 3 o 4 columnas en su plantilla.
  2. Siempre es mejor usar etiquetas Django predeterminadas.

Utilice la etiqueta de la plantilla Django predeterminada ciclo :

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

Se mostrará su lista [1 2 3 4 5 6] como

1 2

3 4

5 6

Por cierto, el motor de plantillas Jinja2 tiene los filtros batch y slice que harán el truco. Cambié a jinja2 y ahora no tengo ninguno de esos problemas de " cómo mostrar x usando etiquetas y filtros de django deficientes "

Creo que tendrá que crear su propia etiqueta de plantilla para realizar divisiones en las consultas. Haría 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)

Ten en cuenta que en realidad no he probado este código, por lo que podría fallar espectacularmente, pero debería apuntarte en la dirección correcta para que eso no esté a la vista.

Aquí hay una solución rápida que utiliza bootstrap y no necesita filtros Django

<div class="row">
    {% for sport in sports %}
        <div class="col-md-6">
            <!-- Blah Blah -->
        </div>
    {% endfor %}
</div>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top