【问题标题】:Jinja2 set block not recognized in DjangoJinja2 设置块在 Django 中无法识别
【发布时间】:2020-06-18 20:09:53
【问题描述】:

我在发布之前搜索了 2 天,所以我真的希望它不是重复的问题。

我正在构建我的第一个 Django 站点,进入它后我意识到我宁愿拥有 jinja2 的力量。我将 jinja2 安装到我的虚拟环境中并对 django 进行了必要的更改(见下文)。但是,django 似乎使用标准 django 模板引擎而不是 jinja2 呈现模板。

使用 {% block content %} 模板内容 {% endblock content %} 时,我的所有代码都按预期工作

我尝试使用 {% set %} 模板内容 {% endset %} 而不是块,以便我可以在 base.html 中复制模板。但我收到此错误:

django.template.exceptions.TemplateSyntaxError: Invalid block tag on line 7: 'set'. Did you forget to register or load this tag?
[05/Mar/2020 22:27:37] "GET /bge/ HTTP/1.1" 500 161659

我对我的项目进行了以下更改以尝试使 jinja2 工作:

设置:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.jinja2.Jinja2'
        ,
        'DIRS': [os.path.join(BASE_DIR, 'templates/jinja2')],
        'APP_DIRS': True,
        'OPTIONS': {
            'environment': 'bge_app.jinja2.environment'
        },
    },
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [(os.path.join(BASE_DIR, 'templates')),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

jinja2.py 添加到 django_projects\bge\bge_app

from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
from jinja2 import Environment


def environment(**options):
    env = Environment(**options)
    env.globals.update({
        'static': staticfiles_storage.url,
        'url': reverse,
    })
    return env

这是 django_projects\bge\bge_app\templates\jinja2\dice.html 中的模板

{% extends "base.html" %}
{% load static %}
{% block title %}
<Title>Dice</Title>
{% endblock title %}

{% set dice_content %}
    <br/>
<div class="container">
    <div class="row">
        <form class="m-3" method="POST">
            {% csrf_token %}
            <div class="input-group">
              <div class="input-group-prepend">
                <button type="submit" class="btn btn-info">Add Die</button>
                {{ die_size_form.num_sides }}
                {{ die_size_form.active }}
              </div>
            </div>
        </form>
        <a href="{% url 'roll_dice' %}">
        <button type="button" class="btn btn-info m-3">Roll Dice</button>
        </a>
        <table class="m-2 table-bordered text-center">
            <tr>
            <th class="p-2">Roll Sum</th>
            </tr>
            <tr>
                <td>
                    {{ active_dice_sum }}
                </td>
            </tr>
        </table>
    </div>
        <table class="table-hover table-bordered text-center table-sm col-md-10">
            <tr>
                <th> Die Sides</th>
                <th> Die Status</th>
                <th> Roll Value</th>
                <th> Remove Die</th>
            </tr>
            {% for die in all_dice %}
                {% if die.active %}
                    {% if die.num_sides == 6 %}
                        <tr>
                            <td>D6 &nbsp;<img src="{% static '/images/dice/d6.png' %}" alt="D 6"></td>
                            <td><a href="{% url 'deactivate_die' die.id %}">
                                <button type="button" class="btn btn-success">Active</button>
                                </a>
                            </td>
                            <td> {{ die.roll_value }} </td>
                            <td><a href="{% url 'remove_die' die.id %}">
                            <button type="button" class="btn btn-danger">X</button>
                            </a>
                            </td>
                        </tr>
                    {% else %}
                        <tr>
                            <td>D {{ die.num_sides }}</td>
                            <td><a href="{% url 'deactivate_die' die.id %}">
                                <button type="button" class="btn btn-success">Active</button>
                                </a>
                            </td>
                            <td> {{ die.roll_value }} </td>
                            <td><a href="{% url 'remove_die' die.id %}">
                                <button type="button" class="btn btn-danger">X</button>
                                </a>
                            </td>
                        </tr>
                    {% endif %}
                {% else %}
                    <tr>
                        <td>D {{ die.num_sides }}</td>
                        <td><a href="{% url 'activate_die' die.id %}">
                            <button type="button" class="btn btn-secondary">Inactive</button>
                            </a>
                        <td> {{ die.roll_value }} </td>
                         <td><a href="{% url 'remove_die' die.id %}">
                        <button type="button" class="btn btn-danger">X</button>
                        </a>
                        </td>
                    </tr>
                {% endif %}
            {% endfor %}
        </table>
{% endset dice_content %}
</div>

这是base.html

{% load static %}
<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

  <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
  <a class="navbar-brand" href="{% url 'index' %}"><i>Board Game Essentials</i></a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNav">
    <ul class="navbar-nav">
      <li class="nav-item active">
        <a class="nav-link" href="{% url 'player_setup' %}">Player Setup</a>
      </li>
      <li class="nav-item active">
        <a class="nav-link" href="{% url 'die_pool' %}">Dice</a>
      </li>
      <li class="nav-item active">
        <a class="nav-link" href="{% url 'hp_tracker' %}">HP Tracker</a>
      </li>
      <li class="nav-item active">
        <a class="nav-link" href="{% url 'score_calc' %}">Score Calculator</a>
      </li>
    </ul>
  </div>
</nav>

{#want to call set multiple times here#}

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
  </body>
</html>

【问题讨论】:

  • 你能显示 base.html 吗? {% set dice_content %} 中的“设置”是什么?
  • 我在我的问题中添加了 base.html。我想将 dice.html 中的所有内容放在一个集合块 {set dice_content} dice.html 的东西 {endset dicecontent} 中,然后在 base.html 中调用它。我可能使用 set 错误,但实际上我更担心 django 无法识别 set 标签,因为这意味着 jinja2 无法正常工作。
  • 您没有在 base.html 中定义任何块。我认为您希望

标签: python django tags set jinja2


【解决方案1】:

base.html(一些变化)

 <!doctype html>
    {% load static %}
    <html lang="en">
      <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>{% block title %} {% endblock %}</title>
        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    </head>
<body>
      <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
      <a class="navbar-brand" href="{% url 'index' %}"><i>Board Game Essentials</i></a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
      <div class="collapse navbar-collapse" id="navbarNav">
        <ul class="navbar-nav">
          <li class="nav-item active">
            <a class="nav-link" href="{% url 'player_setup' %}">Player Setup</a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" href="{% url 'die_pool' %}">Dice</a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" href="{% url 'hp_tracker' %}">HP Tracker</a>
          </li>
          <li class="nav-item active">
            <a class="nav-link" href="{% url 'score_calc' %}">Score Calculator</a>
          </li>
        </ul>
      </div>
    </nav>

    {#want to call set multiple times here#}
    {% block set %}


{% endblock %}
        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
      </body>
    </html>

您的模板

{% extends "base.html" %}
{% block title %}Your webpage title {% endblock %}
{% block set %}
<div class="container">
    <div class="row">
        <form class="m-3" method="POST">
            {% csrf_token %}
            <div class="input-group">
              <div class="input-group-prepend">
                <button type="submit" class="btn btn-info">Add Die</button>
                {{ die_size_form.num_sides }}
                {{ die_size_form.active }}
              </div>
            </div>
        </form>
        <a href="{% url 'roll_dice' %}">
        <button type="button" class="btn btn-info m-3">Roll Dice</button>
        </a>
        <table class="m-2 table-bordered text-center">
            <tr>
            <th class="p-2">Roll Sum</th>
            </tr>
            <tr>
                <td>
                    {{ active_dice_sum }}
                </td>
            </tr>
        </table>
    </div>
        <table class="table-hover table-bordered text-center table-sm col-md-10">
            <tr>
                <th> Die Sides</th>
                <th> Die Status</th>
                <th> Roll Value</th>
                <th> Remove Die</th>
            </tr>
            {% for die in all_dice %}
                {% if die.active %}
                    {% if die.num_sides == 6 %}
                        <tr>
                            <td>D6 &nbsp;<img src="{% static '/images/dice/d6.png' %}" alt="D 6"></td>
                            <td><a href="{% url 'deactivate_die' die.id %}">
                                <button type="button" class="btn btn-success">Active</button>
                                </a>
                            </td>
                            <td> {{ die.roll_value }} </td>
                            <td><a href="{% url 'remove_die' die.id %}">
                            <button type="button" class="btn btn-danger">X</button>
                            </a>
                            </td>
                        </tr>
                    {% else %}
                        <tr>
                            <td>D {{ die.num_sides }}</td>
                            <td><a href="{% url 'deactivate_die' die.id %}">
                                <button type="button" class="btn btn-success">Active</button>
                                </a>
                            </td>
                            <td> {{ die.roll_value }} </td>
                            <td><a href="{% url 'remove_die' die.id %}">
                                <button type="button" class="btn btn-danger">X</button>
                                </a>
                            </td>
                        </tr>
                    {% endif %}
                {% else %}
                    <tr>
                        <td>D {{ die.num_sides }}</td>
                        <td><a href="{% url 'activate_die' die.id %}">
                            <button type="button" class="btn btn-secondary">Inactive</button>
                            </a>
                        <td> {{ die.roll_value }} </td>
                         <td><a href="{% url 'remove_die' die.id %}">
                        <button type="button" class="btn btn-danger">X</button>
                        </a>
                        </td>
                    </tr>
                {% endif %}
            {% endfor %}
        </table>
</div>

 {% endblock %}

您在基本模板{% block your_block_name %}{% endblock %}中定义块并在子模板中使用这些块。如果您有任何错误或不理解答案,请告诉我。此外,您不必安装任何东西(如 jinja2)。 Django 已经支持此功能。

【讨论】:

  • 非常感谢您抽出宝贵时间调查我的问题。我知道 {block}{endblock} 是如何工作的,并且在我的问题中我说我的代码在使用块时确实可以工作。但是,您不能在 base.html 中多次调用同一个块,这是我想要做的。所以为此我需要使用宏或设置,这就是我想使用 jinja2 的原因。稍后我还想要一些其他的 jinja2 功能,但现在我真的很想看到 jinja2 在 django 中被识别。我一定遗漏了一些明显的东西,但我只是没有看到。
猜你喜欢
  • 2017-06-08
  • 2016-10-09
  • 2017-01-04
  • 1970-01-01
  • 2019-09-17
  • 2015-12-11
  • 2013-06-02
  • 2021-08-25
  • 2013-02-09
相关资源
最近更新 更多