Jinja2 设置块在 Django 中无法识别
Posted
技术标签:
【中文标题】Jinja2 设置块在 Django 中无法识别【英文标题】:Jinja2 set block not recognized in 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 <img src="% static '/images/dice/d6.png' %" ></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 中定义任何块。我认为您希望 【参考方案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 <img src="% static '/images/dice/d6.png' %" ></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 已经支持此功能。
【讨论】:
非常感谢您抽出宝贵时间调查我的问题。我知道 blockendblock 是如何工作的,并且在我的问题中我说我的代码在使用块时确实可以工作。但是,您不能在 base.html 中多次调用同一个块,这是我想要做的。所以为此我需要使用宏或设置,这就是我想使用 jinja2 的原因。稍后我还想要一些其他的 jinja2 功能,但现在我真的很想看到 jinja2 在 django 中被识别。我一定遗漏了一些明显的东西,但我只是没有看到。以上是关于Jinja2 设置块在 Django 中无法识别的主要内容,如果未能解决你的问题,请参考以下文章
使用 jinja2 作为 django 模板引擎时出错:无法导入名称“环境”
Django OAuth 2 客户端设置 - 客户端无法识别令牌