60 votes

Autre coloration de lignes dans un modèle Django avec plusieurs jeux de lignes

Modèles Django offre la builtin tag cycle pour alterner entre plusieurs valeurs à différents points dans un modèle (ou pour la boucle dans un modèle), mais cette balise n'est pas réinitialisée lorsque l'on accède à un champ d'application à l'extérieur de l' cycles définition. I. e., si vous avez deux ou plusieurs listes dans votre modèle, les lignes de tout ce dont vous souhaitez utiliser un peu de css définitions odd et even, la première ligne d'une liste reprendra là où le dernier à gauche, avec une nouvelle itération de choix (odd et even)

E. g., dans le code suivant, si le premier blog a un nombre impair d'entrées, la première entrée dans un deuxième blog va commencer comme d' even,, quand je veux la démarrer en odd.

{% for blog in blogs %}
  {% for entry in blog.entries %}
    <div class="{% cycle 'odd' 'even' %}" id="{{entry.id}}">
      {{entry.text}}
    </div>
  {% endfor %}
{% endfor %}

J'ai essayé de parer à ce en bidouillant avec l' resetcycle balise offert ici:

Django billet: le Cycle de la balise devrait se réinitialiser après il fait un pas hors de portée

en vain. (Le code ne fonctionne pas pour moi.)

J'ai aussi essayé de bouger ma boucle interne dans une balise personnalisée, mais cela n'a pas fonctionné, peut-être parce que la compilation/render cycle déplace le retour de boucle dans la boucle externe? (Quelle que soit la raison, il ne fonctionne pas pour moi.)

Comment puis-je accomplir cette tâche simple!? Je préfère ne pas créer une structure de données, à mon avis avec cette information pré-compilé, ce qui semble inutile. Merci à l'avance.

113voto

Carl Meyer Points 30736

La solution de contournement la plus simple (jusqu'à ce que le correctif resetcycle soit corrigé et appliqué) consiste à utiliser le filtre "divisibleby" intégré avec forloop.counter:

 {% for entry in blog.entries %}
  <div class="{% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}" id="{{ entry.id }}">
    {{ entry.text }}
  </div>
{% endfor %}
 

Un peu plus verbeux, mais pas difficile à comprendre et ça marche très bien.

3voto

hasenj Points 36139

Abandonner et utiliser Jinja2 Système de Template

J'ai renoncé à django langage de template, il est très limité dans ce que vous pouvez faire avec lui. Jinja2 utilise la même syntaxe que le django template utilise, mais ajoute de nombreuses améliorations par rapport à elle.

MODIFIER/REMARQUE ( je sais, ça sonne comme un big switch pour juste un problème mineur, mais en réalité, je parie que vous avez toujours vous retrouver lutte contre le défaut du système de template de django, donc c'est vraiment la peine et je crois qu'il va vous rendre plus productif sur le long terme. )

Vous pouvez lire cet article écrit par son auteur, même s'il est technique, il mentionne le problème de la {% cycle %} la balise dans django.

Jinja n'ont pas un cycle de balise, il a un cycle de méthode sur la boucle:

{% for user in users %}
    <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li>
{% endfor %}

Un avantage majeur de Jinja2, c'est qu'il vous permet d'utiliser la logique pour la présentation, donc si vous avez une liste de photos, vous pouvez les mettre dans un tableau, parce que vous pouvez commencer une nouvelle ligne dans une table tous les éléments N, voir, vous pouvez le faire par exemple:

{% if loop.index is divisibleby(5) %}   
     </tr>
     {% if not loop.last %}
     <tr>
     {% endif %}
{% endif %}

vous pouvez également utiliser des expressions mathématiques:

{% if x > 10 %}

et vous pouvez accéder à vos fonctions python directement (mais certains est la configuration requise pour spécifier les fonctions doivent être exposés pour le modèle)

{% for item in normal_python_function_that_returns_a_query_or_a_list() %}

même définir des variables ..

{% set variable_name = function_that_returns_an_object_or_something() %}

2voto

pkdkk Points 365

Je finis par le faire avec le forloop.counter0 - Cela fonctionne très bien!

 {% for product in products %}

    {% if forloop.counter0|divisibleby:4 %}<div class="clear"></div>{% endif %}

    <div class="product {% if forloop.counter0|divisibleby:4 %}col{% else %}col20{% endif    %}">
        Lorem Ipsum is simply dummy text
    </div>

{% endfor %}
 

1voto

Steve Losh Points 11958

La réponse la plus simple pourrait être: "abandonnez et utilisez jQuery". Si cela est acceptable, c'est probablement plus facile que de se battre avec les modèles de Django pour une chose aussi simple.

-5voto

orip Points 28225

Il existe un moyen de le faire côté serveur avec un itérateur qui ne conserve pas une copie simultanée de toutes les entrées:

 import itertools
return render_to_response('template.html',
  {
    "flattened_entries": itertools.chain(*(blog.entries for blog in blogs)),
  })
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X