我想根据请求添加不同的模板。例如:
假设该请求具有:
request.country = 'Spain'
request.city = 'Madrid'
我想要包含“index.html”视图,但是:
----如果myapp / index_madrid.html存在
{% include "myapp/index_madrid.html" %}
---- elif myapp / index_spain.html存在
{% include "myapp/index_spain.html" %}
----否则转到默认版本
{% include "myapp/index.html" %}
如何以透明的方式实现此行为?我的意思是,我想做类似的事情:
{% my_tag_include "myapp/index.html" %}
{% my_tag_include "myapp/another_view.html" with p='xxx' only%}
{% my_tag_include "myapp/any_view.html" with p='sss' a='juan' %}
并实现我之前解释过的级联加载。
由于
答案 0 :(得分:2)
您可以实现自定义模板标记来检查模板是否存在:
from django import template
register = template.Library()
def template_exists(template_name):
try:
django.template.loader.get_template(template_name)
return True
except template.TemplateDoesNotExist:
return False
register.filter('template_exists', template_exists)
在你的模板中:
{% if template_exists "myapp/index_"add:request.city|add:".html" %}
{% include "myapp/index_"add:request.city|add:".html" %}
{% elif template_exists "myapp/index_"add:request.country|add:".html" %}
{% include "myapp/index_"add:request.country|add:".html" %}
{% else %}
{% include "myapp/index.html" %}
修改: 您可以通过模板标记完成所有逻辑:
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def existing_template(context):
request = context["request"]
if django.template.loader.get_template("myapp/index_"+ request.city+".html"):
return "myapp/index_"+ request.city+".html"
elif django.template.loader.get_template("myapp/index_"+ request.country+".html"):
return "myapp/index_"+ request.country+".html"
else:
return "myapp/index.html"
在你的模板中:
{% include required_template %}
答案 1 :(得分:2)
一种可能性是在视图中实现这种逻辑:
# views.py
from django.template.loader import select_template
class MyView(View):
def get(self, request):
include_template = select_template([
'myapp/index_{}.html'.format(request.city),
'myapp/index_{}.html'.format(request.country),
'myapp/index.html'
])
ctx = {
'include_template': include_template
}
return render(request, 'myapp/base.html', ctx)
# myapp/base.html
{% include include_template %}
select_template() 将返回已存在的传递列表中的第一个模板。 include
标记支持包含从Django 1.7
开始的已编译模板,因此如果您使用的是1.7或更高版本,这应该可以正常工作。
更新:重复使用多个视图
# utils.py
from django.template.loader import select_template
def get_approriate_template(tokens, app_name):
templates = ['{}/index_{}.html'.format(app_name, x) for x in tokens]
templates.append('{}/index.html'.format(app_name))
return select_template(templates)
# views.py
from .utils import get_approriate_template
class MyView(View):
def get(self, request):
tokens = [request.city, request.country]
ctx = {
'include_template': get_appropriate_template(tokens, app_name='myapp')
}
return render(request, 'myapp/base.html', ctx)
更新:从模板标记中呈现模板
# templatetags/myapp_extras.py
from django import template
register = template.Library()
@register.simple_tag(takes_context=True)
def my_tag_include(context):
from django.template.loader import select_template
include_template = select_template([
'myapp/index_{}.html'.format(context['request'].city),
'myapp/index_{}.html'.format(context['request'].country),
'myapp/index.html'
])
return include_template.render(context)
# myapp/base.html
{% load myapp_extras %}
{% my_tag_include %}
答案 2 :(得分:1)
您可以通过编写自己的模板标记来执行此操作,该标记返回存在的有效模板。
方法-1使用Script Error.
:
<强> some_app / templatetags / some_app_extras.py 强>
var window = {google: {}};
var google = {maps: {}};
(function() {
function getScript(src) {
importScripts(src);
//document.write('<' + 'script src="' + src + '"><' + '/script>');
}
var modules = google.maps.modules = {};
google.maps.__gjsload__ = function(name, text) {
modules[name] = text;
};
google.maps.Load = function(apiLoad) {
delete google.maps.Load;
apiLoad([0.009999999776482582,[[["http://mt0.googleapis.com/vt?lyrs=m@306000000\u0026src=api\u0026hl=de-DE\u0026","http://mt1.googleapis.com/vt?lyrs=m@306000000\u0026src=api\u0026hl=de-DE\u0026"],null,null,null,null,"m@306000000",["https://mts0.google.com/vt?lyrs=m@306000000\u0026src=api\u0026hl=de-DE\u0026","https://mts1.google.com/vt?lyrs=m@306000000\u0026src=api\u0026hl=de-DE\u0026"]],[["http://khm0.googleapis.com/kh?v=174\u0026hl=de-DE\u0026","http://khm1.googleapis.com/kh?v=174\u0026hl=de-DE\u0026"],null,null,null,1,"174",["https://khms0.google.com/kh?v=174\u0026hl=de-DE\u0026","https://khms1.google.com/kh?v=174\u0026hl=de-DE\u0026"]],[["http://mt0.googleapis.com/vt?lyrs=h@306000000\u0026src=api\u0026hl=de-DE\u0026","http://mt1.googleapis.com/vt?lyrs=h@306000000\u0026src=api\u0026hl=de-DE\u0026"],null,null,null,null,"h@306000000",["https://mts0.google.com/vt?lyrs=h@306000000\u0026src=api\u0026hl=de-DE\u0026","https://mts1.google.com/vt?lyrs=h@306000000\u0026src=api\u0026hl=de-DE\u0026"]],[["http://mt0.googleapis.com/vt?lyrs=t@132,r@306000000\u0026src=api\u0026hl=de-DE\u0026","http://mt1.googleapis.com/vt?lyrs=t@132,r@306000000\u0026src=api\u0026hl=de-DE\u0026"],null,null,null,null,"t@132,r@306000000",["https://mts0.google.com/vt?lyrs=t@132,r@306000000\u0026src=api\u0026hl=de-DE\u0026","https://mts1.google.com/vt?lyrs=t@132,r@306000000\u0026src=api\u0026hl=de-DE\u0026"]],null,null,[["http://cbk0.googleapis.com/cbk?","http://cbk1.googleapis.com/cbk?"]],[["http://khm0.googleapis.com/kh?v=86\u0026hl=de-DE\u0026","http://khm1.googleapis.com/kh?v=86\u0026hl=de-DE\u0026"],null,null,null,null,"86",["https://khms0.google.com/kh?v=86\u0026hl=de-DE\u0026","https://khms1.google.com/kh?v=86\u0026hl=de-DE\u0026"]],[["http://mt0.googleapis.com/mapslt?hl=de-DE\u0026","http://mt1.googleapis.com/mapslt?hl=de-DE\u0026"]],[["http://mt0.googleapis.com/mapslt/ft?hl=de-DE\u0026","http://mt1.googleapis.com/mapslt/ft?hl=de-DE\u0026"]],[["http://mt0.googleapis.com/vt?hl=de-DE\u0026","http://mt1.googleapis.com/vt?hl=de-DE\u0026"]],[["http://mt0.googleapis.com/mapslt/loom?hl=de-DE\u0026","http://mt1.googleapis.com/mapslt/loom?hl=de-DE\u0026"]],[["https://mts0.googleapis.com/mapslt?hl=de-DE\u0026","https://mts1.googleapis.com/mapslt?hl=de-DE\u0026"]],[["https://mts0.googleapis.com/mapslt/ft?hl=de-DE\u0026","https://mts1.googleapis.com/mapslt/ft?hl=de-DE\u0026"]],[["https://mts0.googleapis.com/mapslt/loom?hl=de-DE\u0026","https://mts1.googleapis.com/mapslt/loom?hl=de-DE\u0026"]]],["de-DE","US",null,0,null,null,"http://maps.gstatic.com/mapfiles/","http://csi.gstatic.com","https://maps.googleapis.com","http://maps.googleapis.com",null,"https://maps.google.com","https://gg.google.com","http://maps.gstatic.com/maps-api-v3/api/images/","https://www.google.com/maps",0],["http://maps.gstatic.com/maps-api-v3/api/js/21/3/intl/de_ALL","3.21.3"],[141790386],1,null,null,null,null,null,"",["geometry"],null,0,"http://khm.googleapis.com/mz?v=174\u0026","AIzaSyDQi59vEjsIzBM-AFMeDbszVsOckQOb5A8","https://earthbuilder.googleapis.com","https://earthbuilder.googleapis.com",null,"http://mt.googleapis.com/vt/icon",[["http://mt0.googleapis.com/vt","http://mt1.googleapis.com/vt"],["https://mts0.googleapis.com/vt","https://mts1.googleapis.com/vt"],null,null,null,null,null,null,null,null,null,null,["https://mts0.google.com/vt","https://mts1.google.com/vt"],"/maps/vt",306000000,132],2,500,[null,"http://g0.gstatic.com/landmark/tour","http://g0.gstatic.com/landmark/config",null,"http://www.google.com/maps/preview/log204","","http://static.panoramio.com.storage.googleapis.com/photos/",["http://geo0.ggpht.com/cbk","http://geo1.ggpht.com/cbk","http://geo2.ggpht.com/cbk","http://geo3.ggpht.com/cbk"]],["https://www.google.com/maps/api/js/master?pb=!1m2!1u21!2s3!2sde-DE!3sUS!4s21/3/intl/de_ALL","https://www.google.com/maps/api/js/widget?pb=!1m2!1u21!2s3!2sde-DE"],null,0,0,"/maps/api/js/ApplicationService.GetEntityDetails",0], loadScriptTime);
};
importScripts(
'http://maps.gstatic.com/maps-api-v3/api/js/21/3/intl/de_ALL/main.js'
, 'http://maps.gstatic.com/maps-api-v3/api/js/21/3/intl/de_ALL/geometry.js'
);
})();
在您的模板中:
assignment_tag
我们使用赋值标记,并在注册标记时通过传递from django import template
from django.template.loader import select_template
register = template.Library()
@register.assignment_tag(takes_context=True)
def get_valid_template(context):
city_template = 'myapp/index_{}.html'.format(context['request'].city)
country_template = 'myapp/index_{}.html'.format(context['request'].country)
index_template = 'myapp/index.html'
templates_list = [city_template, country_template, index_template]
valid_template = select_template(templates_list)
return valid_template.name
参数将上下文传递给它。由于我们有上下文,因此我们可以访问{% load some_app_extras %}
{% get_valid_template as valid_template %}
{% include valid_template %}
以获取takes_context=True
和request
。在此之后,我们使用django的city
函数并传递一个模板列表,这些模板将返回列表中找到的第一个模板。
然后在我们的模板中,我们可以使用此模板标记获取country
并使用此变量来呈现select_template()
。
方法-2使用valid template
:
如果您只想按照评论中提到的那样在1行中进行渲染,那么您可以使用valid template
。您不需要在变量中分配模板名称,然后由simple_tag
内置模板标记稍后完成渲染。 simple_tag
将自动显示必要的模板,因为它已经在模板标记代码中呈现。
<强> some_app / templatetags / some_app_extras.py 强>
include
在您的模板中:
get_template_tag
答案 3 :(得分:0)
最后,我通过创建自定义简单标记解决了问题,例如:
@register.simple_tag(takes_context=True)
def my_own_include(context, *args):
#I get the request and create a list of possible template views
return select_template(list_of_posible_views).render(context)
在.html文件中,我将此标记称为:
{% my_own_include 'index.html' %}
感谢各位的帮助。