Skip to main content
 首页 » 编程设计

python之模板包含标记 : Choose another template if it does not exist

2025年05月04日37cmt

我想根据请求包含一个不同的模板。例如:

假设请求有:

request.country = 'Spain' 
request.city = 'Madrid' 

我想包含“index.html” View 但是:

----如果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' %} 

并实现我之前解释的级联加载。

谢谢

请您参考如下方法:

一种可能是在 View 中实现这种逻辑:

# 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 或更高版本,这应该可以正常工作。


更新:跨多个 View 重用

# 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 %}