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

Les modèles Django offrent le cycle balise intégré pour alterner plusieurs valeurs à différents points d’un modèle (ou pour une boucle dans un modèle), mais cette balise n’est pas réinitialisée lorsqu’elle est accessible dans une étendue en dehors de la définition du cycle . C’est-à-dire que si vous avez deux listes ou plus dans votre modèle, les lignes de toutes les définitions CSS que vous souhaitez utiliser sont odd et even . La première ligne d’une liste reprendra la dernière itération fraîche des choix ( odd et even )

Par exemple, dans le code suivant, si le premier blog a un nombre impair d’entrées, alors la première entrée d’un deuxième blog commencera even si je veux commencer à un nombre odd .

 {% for blog in blogs %} {% for entry in blog.ensortinges %} 
{{entry.text}}
{% endfor %} {% endfor %}

J’ai essayé d’éviter ce resetcycle le resetcycle proposé ici:

Ticket Django: la balise de cycle doit être réinitialisée après avoir dépassé la scope

en vain. (Le code n’a pas fonctionné pour moi.)

J’ai également essayé de déplacer ma boucle interne dans une balise personnalisée, mais cela ne fonctionnait pas non plus, peut-être parce que le cycle de compilation / rendu ramène la boucle dans la boucle externe? (Peu importe pourquoi, cela n’a pas fonctionné 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 ces informations pré-compilées; cela semble inutile. Merci d’avance.

La solution 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.ensortinges %} 
{{ entry.text }}
{% endfor %}

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

Vous pouvez utiliser les resetcycle cycle et de resetcycle (nouveaux dans Django 1.11) (depuis https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#std:templatetag-resetcycle ):

 {% for blog in blogs %} {% cycle 'odd' 'even' as rowcolors silent %} {% resetcycle rowcolors %} {% for entry in blog.ensortinges %} {% cycle rowcolors %} 
{{ entry.text }}
{% endfor %} {% endfor %}

Je finis par le faire, avec le forloop.counter0 – ça marche très bien!

 {% for product in products %} {% if forloop.counter0|divisibleby:4 %}
{% endif %}
Lorem Ipsum is simply dummy text
{% endfor %}

La réponse la plus simple pourrait être: “abandonner et utiliser jQuery”. Si cela est acceptable, c’est probablement plus facile que de se battre avec les modèles de Django sur quelque chose d’aussi simple.

Abandonnez et utilisez Jinja2 Template System

J’ai abandonné le langage des templates de django, il est très restreint dans ce que vous pouvez faire avec. Jinja2 utilise la même syntaxe que celle utilisée par le modèle django, mais ajoute de nombreuses améliorations par rapport à celui-ci.

EDIT / NOTE (Je sais que cela ressemble à un gros changement pour un problème mineur, mais en réalité, je parie que vous vous retrouvez toujours à combattre le système de template par défaut dans django, donc ça en vaut vraiment la peine et le long terme. )

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

Jinja n’a pas d’étiquette de cycle, il a une méthode de cycle sur la boucle:

 {% for user in users %} 
  • {{ user }}
  • {% endfor %}

    Un avantage majeur de Jinja2 est qu’il vous permet d’utiliser la logique pour la présentation, donc si vous avez une liste d’images, vous pouvez les placer dans un tableau, car vous pouvez démarrer une nouvelle ligne dans un tableau tous les N éléments, voir vous pouvez faire par exemple:

     {% if loop.index is divisibleby(5) %}  {% if not loop.last %}  {% endif %} {% endif %} 

    vous pouvez également utiliser des expressions mathématiques:

     {% if x > 10 %} 

    et vous pouvez accéder directement à vos fonctions python (mais une certaine configuration est nécessaire pour spécifier les fonctions à exposer 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() %} 

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

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