Question

Existe-t-il un moyen efficace de convertir l'énumération d'un ensemble de requêtes en deux colonnes div ?

En utilisant la grille 960, j'ai quelque chose à l'effet de ...

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

Dans Django, un modèle doit avoir son contenu énuméré rendu dans ces deux colonnes, et de préférence à peu près de la même manière. Pour le moment, j'ai un code moche qui, dans la vue, divise le QuerySet en 2 moitiés, puis chaque moitié est rendue dans leur colonne respective.

Il doit exister un meilleur moyen de le faire, de préférence en n'utilisant que le système de rendu des modèles?

Juste pour référence, voici comment cela fonctionne " " pour le moment:

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>
Était-ce utile?

La solution

Je recommande d'utiliser les filtres Django .

Les extraits Django fournissent un filtre de modèle de partitionnement , que vous pouvez utiliser comme:

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

Autres conseils

  1. C'est la tâche d'un système de rendu, pas de vue. La vue ne doit pas savoir si vous allez afficher 2, 3 ou 4 colonnes dans votre modèle.
  2. Il est toujours préférable d'utiliser les balises Django par défaut.

Utiliser la balise de modèle Django par défaut 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>

Cela affichera votre liste [1 2 3 4 5 6] comme

1 2

3 4

5 6

En passant, le moteur de template Jinja2 a des filtres batch et slice qui feront l'affaire. Je suis passé à jinja2 et je n’ai plus aucun de ces problèmes de "comment afficher x à l’aide de balises et de filtres django médiocres"

Je pense que vous devrez créer votre propre balise de gabarit pour séparer les requêtes. Je voudrais faire quelque chose comme.

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)

Veuillez noter que je n'ai pas encore testé ce code. Il risque donc d'échouer de façon spectaculaire, mais il devrait vous indiquer la bonne direction à suivre pour obtenir ces informations.

Voici une solution rapide utilisant le bootstrap et ne nécessitant aucun filtre Django

<div class="row">
    {% for sport in sports %}
        <div class="col-md-6">
            <!-- Blah Blah -->
        </div>
    {% endfor %}
</div>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top