在 Django 中,如何使用模板和 DB 对象中使用的动态 URL 实现样板 HTML 变量?
Posted
技术标签:
【中文标题】在 Django 中,如何使用模板和 DB 对象中使用的动态 URL 实现样板 HTML 变量?【英文标题】:In Django, how to implement boilerplate HTML variables with Dynamic URLs used in templates and DB objects? 【发布时间】:2020-01-08 21:28:34 【问题描述】:在 Django 中,在我的数据库中,我创建了包含样板 html 和动态 URL 的字符串变量,但我无法让它们在我的模板中工作。
我使用的是 render_as_template (https://github.com/danielrozenberg/django-render-as-template/blob/master/render_as_template/templatetags/render_as_template.py),所以动态 URL 可以工作。我尝试了自定义模板标签,但是当我将它们与 render_as_template 一起使用时,它无法加载。
然后我尝试了自定义上下文处理器。我在上下文处理器中创建了两个函数,一个用于超链接,一个用于工具提示。我让工具提示处理器工作,但我只能通过查询集中自动生成的字典中的编号在模板中引用它们。
我对超链接处理器做了同样的事情,然后尝试修改它以使用字符串键而不是整数,但它不会加载所有字段。我一定是错过了什么。
custom_tags.py
from django import template
register = template.Library()
@register.simple_tag
def rdo_hyper():
value = Boilerplate.objects.filter(name='RDO').values_list('hyperlink',flat=True)
return value[0]
# It's only going to return one field.
# Expected output: <a href="% url 'guides:rdo' %" target=”_blank” rel=”noopener noreferrer”>Foobar</a>
# tried a non-DB version, just in case
@register.simple_tag
def rdo_hyper2():
value = "<a href=\"% url \'guides:rdo\' %\" target=\”_blank\” rel=\”noopener noreferrer\”>Foobar</a>"
return value
# Expected output: <a href="% url 'guides:rdo' %" target=”_blank” rel=”noopener noreferrer”>Foobar</a>
custom_context.py
from myapp.apps.wizard.models import Boilerplate
def boilerplate_hyperlink_processor(request):
boilerplate_hyper =
"foo": Boilerplate.objects.filter(name='Aftermarket').values_list('hyperlink',flat=True),
"bar": Boilerplate.objects.filter(name='Sights').values_list('hyperlink',flat=True)
return 'boilerplate_hyper': boilerplate_hyper
# Expected output of boilerplate_hyper.foo:
#<a href="% url 'guides:aftermarket' %" target=”_blank” rel=”noopener noreferrer”>Aftermarket Support</a>
#
# Expected output of boilerplate_hyper.bar:
# <a href="% url 'guides:sights' %" target=”_blank” rel=”noopener noreferrer”>Sights</a>
def boilerplate_tooltip_processor(request):
boilerplate_tooltip = Boilerplate.objects.values_list('tooltip',flat=True)
return 'boilerplate_tooltip': boilerplate_tooltip
# Expected output of boilerplate_tooltip.0:
#<sup><a href="% url 'guides:sights' %" target=”_blank” rel=”noopener noreferrer” data-html="true" class="fas fa-info-circle pr-2" aria-hidden="true" data-toggle="tooltip" data-placement="top" title="Insert helpful tooltip info here.<br/><strong>Click</strong> for more info."></a></sup>
template.html
% load static %
% load custom_tags %
% rdo_hyper as rdo_hyper %
% rdo_hyper2 as rdo_hyper2 %
% load render_as_template %
...
<html>
% autoescape off %
1. % rdo_hyper %
2. rdo_hyper
3. % rdo_hyper2 %
4. rdo_hyper2
5. % render_as_template rdo_hyper %
6. boilerplate_hyper.foo
7. % render_as_template boilerplate_hyper.foo %
8. % render_as_template boilerplate_tooltip.0 %
% endautoescape %
# The hyperlink value is:
<a href="% url 'guides:aftermarket' %" target=”_blank” rel=”noopener noreferrer”>
Aftermarket Support</a> #
</html>
在template.html中,发生以下情况:
-
呈现,但动态 URL 失败。
根本不呈现变量。否则页面加载正常。
呈现,但动态 URL 失败。
根本不呈现变量。否则页面加载正常。
根本不呈现变量。否则页面加载正常。
仅呈现“售后支持”]>”,而不是来自 DB 的完整超链接字段。
抛出此错误:
TemplateSyntaxError:
In template <unknown source>, error at line 1.
Could not parse the remainder: '\'guides:aftermarket\'' from '\'guides:aftermarket\''
1 <QuerySet ['<a href="% url \'guides:aftermarket\' %" target=”_blank” rel=”noopener noreferrer”>Aftermarket Support</a>']>
-
工作正常。
% render_as_template Boilerplate_tooltip.0 % 很好用,但我更愿意通过字符串键引用模板中的变量。毕竟,Django 模板语言的精神是它的模板可以被非程序员读写。有什么想法吗?
【问题讨论】:
你为什么要这样做? 我有一些工具提示和超链接,它们在整个网站中多次出现。如果我必须更新它们中的任何一个,我将不得不检查它们使用的每个实例(每个工具提示 30 多次)。如果可能,我宁愿只更新一次变量。干燥。 en.wikipedia.org/wiki/Don%27t_repeat_yourself 哦,如果有帮助,我也会在数据库字段中使用这些样板变量。无论哪种方式,我都需要使用 % render as template % 或使动态 URL 正常运行的东西。我可以为我的变量尝试模板,而不是上下文处理器或自定义标签。在项目的后期,我将使用 webscraper 从几个外部 URL 中选择一个,所以我认为 DB 非常适合存储当前的最佳 URL。但是,这些将是外部 URL,而不是项目内的动态 URL。 【参考方案1】:我回去尝试自定义标签,这似乎有效:
custom_tags.py
@register.simple_tag(takes_context=True)
def rdo_hyper2(context):
value = "<a href=\"% url \'guides:rdo\' %\" target=\”_blank\” rel=\”noopener noreferrer\”>Foobar</a>"
rendered = context.template.engine.from_string(value).render(context)
return rendered
template.html
% load custom_tags %
...
% rdo_hyper2 %
当在数据库字段中包含 % rdo_hyper2 % 或其他自定义标签时,我还必须每次都在该字段的顶部使用 % load custom_tags % 否则它会抛出:
Invalid block tag on line 12: 'rdo_hyper2'. Did you forget to register or load this tag?
希望这不是资源密集型的!
【讨论】:
以上是关于在 Django 中,如何使用模板和 DB 对象中使用的动态 URL 实现样板 HTML 变量?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 django 模板中的一行中显示来自 db 的输出文本