web-dev-qa-db-fra.com

django: utiliser des blocs dans les modèles inclus

J'ai des structures HTML qui sont réutilisées dans pas mal d'endroits différents. Il est différent d'un modèle global et ne peut donc pas être étendu. Il peut également être utilisé pour contenir un contenu complexe. Par conséquent, je ne pense pas que le définir en tant que balise de modèle fasse un bon travail. Ci-dessous se trouve un pseudo code décrivant le résultat souhaité. Lorsque vous utilisez template_level2.html, vous pouvez facilement insérer des éléments dans le fichier reusable_pattern_template en appelant le bloc qui s’y trouve. Si j'utilise ce code, ce que vous écrivez dans le "contenu actuel" de template_level_2.html ne sera pas affiché. Comment devrais-je gérer cela? 

base.html

<html>
<head></head>
<body>
{% block content %}{% endblock %}
</body>
</html>

template_level1.html

{% extends 'base.html' %}
{% block content %}
  Something here...
  {% include 'reusable_pattern_template.html' %}
  Something else here...
{% endblock %}

réutilisable_pattern_template.html

<div>
  <div>
    <div>
      {% block local_content %}{% endblock %}
    </div>
   </div>
</div>

template_level2.html

{% extends 'template_level1.html' %}
{% block local_content %}
  Actual content here...
{% endblock %}

update: Désolé, l'extension dans template_level2.html présente des erreurs d'orthographe, je viens de le corriger.

Ce n'est peut-être pas très clair, mais le code ci-dessus est plutôt un pseudo-code décrivant le résultat souhaité. En bref, 

  • Je voudrais inclure de petits morceaux de modèles HTML réutilisables dans mes modèles
  • Ces modèles ressemblent à des boîtes dans lesquelles vous pouvez mettre des morceaux entiers de contenu HTML En eux. Donc, les variables de contexte peuvent être un peu trop limitées pourmy
33
Xun Yang

Django ne traite pas les blocs dans les fichiers inclus.

La balise include doit être considérée comme une implémentation de "afficher ce sous-modèle et inclure le code HTML", et non comme "analyser ce sous-modèle et inclure son contenu comme s'il faisait partie du parent". Cela signifie qu'il n'y a pas d'état partagé entre les modèles inclus - chaque inclusion est un processus de rendu complètement indépendant. ( Documentation de balise de modèle Django )

47
Chris Pratt

Il semble que le modèle final tente de s’étendre (s’il était entre guillemets) .

Vous n'avez vraiment pas besoin de beaucoup de complexité. C'est en fait beaucoup plus simple.

Le modèle de base doit contenir le squelette de votre modèle. Vous pouvez ensuite l'étendre pour effectuer des personnalisations. Pour les blocs de code réutilisables que vous ne souhaitez pas inclure dans chacune de vos vues, include si nécessaire, mais n'utilisez aucune instruction block, extends ou include dans le fichier inclus. Django ne les analysera pas, mais le context variable transmis depuis la vue peut toujours être utilisé.

3
Umur Kontacı

Je suis tombé sur ce problème et je me suis retrouvé avec le compromis suivant, en espérant que quelqu'un d'autre le trouverait utile. Il repose sur l'utilisation de blocs with dans les modèles enfants.

base.html veut réutiliser un commun nav.html include, mais définit certains blocs dans lesquels les variables de nav.html peuvent être remplacées par des modèles enfants.

<!-- base.html: -->
<html>
  [...]
  <nav class="desktop">
    {% block desktop_nav %}
      {% include "includes/nav.html" %}
    {% endblock %}
  </nav>
  [...]
  <nav class="mobile">
    {% block mobile_nav %}
      {% include "includes/nav.html" %}
    {% endblock %}
  </nav>
  [...]

Le modèle d'inclusion dépend d'une variable appelée selected, que base.html ne définit pas, par défaut:

<!--includes/nav.html:-->
<a href="/about/" class="{% if selected == 'about' %}selected{% endif %}">About</a>
<a href="/people/" class="{% if selected == 'people' %}selected{% endif %}">People</a>
<a href="/contact/" class="{% if selected == 'contact' %}selected{% endif %}">Contact</a>

Mais les pages enfants peuvent remplacer cette valeur comme suit:

<!--about.html:-->
{% extends "base.html" %}
{% block desktop_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}
{% block mobile_nav %}{% with selected='about' %}{{ block.super }}{% endwith %}{% endblock %}

donc, pas parfait, je dois toujours avoir deux blocs distincts et utiliser deux fois les blocs with, mais cela me permet de remplacer les variables des blocs include du modèle parent.

2
hwjp

Vous pouvez scinder reusable_pattern_template en modèles de début et de fin. Ensuite, au niveau 1, vous pouvez aller inclure, commencer, bloquer, inclure la fin.

Vous pouvez également passer un nom de modèle dans reusable_pattern_template en tant que variable de contexte, puis l'inclure dans reusable_pattern_template. Cela nécessitera de changer la relation entre level1 et level2 dans votre exemple, mais sera généralement plus puissant.

0
Gordon Wrigley