1

商业:

网页应用程序设计的实用背景,其中网页由原型对象、小工具构建,它们在自己的view函数中单独定义每个对象(它自己的代码,不一定是 django-view 函数)。并且为了构建一个“生产”网页,它们可以放置在与该页面相关的常规视图中,并根据给定的源数据和其他参数生成网页元素。例如,我有一个图表小工具,它接收源数据、参数、关于图表类型、美/颜色等,并绘制图表。如何将它与特定的应用程序分开存储,松散耦合的代码?哪种设计方法更好?

我试过的:

我试过“愚蠢”的方式:

例如我有一个简单的观点:

from django.shortcuts import render_to_response
from django.template import Template, Context
from string import letters
def home(request):
    t = Template("""<ul>
                        {% for key, value in d.items %}
                            <li>{{ key }}: {{ value }}</li>
                        {% endfor %}
                    </ul>""")
    d = {k: v for v, k in enumerate(letters)}
    return render_to_response('home.html', {'t': t, 'd':d})

和模板:

<html>
<head>
    <title>Django tests</title>

</head>
<body>
{% include t with d=d %}
</body>
</html>

通过这样的设置,我得到:TemplateDoesNotExist

对答案的期望:

我正在寻找任何合理的方案来存储网页块,该方案旨在以自己的方式生活,与网页的其他元素或多或少地分开,在网络应用程序后端的类似单独的代码块中. 例如,我可以提供以下项目:

谢谢!




ps

来自 django-docs 的摘录:

{% extends variable %} 使用变量的值。如果变量的计算结果为字符串,Django 将使用该字符串作为父模板的名称。如果变量的计算结果为 Template 对象,Django 将使用该对象作为父模板。

所以这意味着,使用 {% extends %} 标签,我所说的操作绝对是可能的。

此示例包括名称包含在变量 template_name 中的模板的内容:

{% include template_name %}

所以这可能意味着,传递给的变量{% include %}可以只是一个带有文件名的字符串。如果它是真的,那么我的问题的答案就很明确了——在变量中定义的模板不能包含在常规模板中。
它对我来说仍然有点模棱两可,因为在 Python 中这个词name可能被用作variable.

4

4 回答 4

3

正如评论中已经提到的那样,您只需将模板呈现为字符串并将其传递给第二个模板,将其标记为安全字符串,因此不会自动转义。所以,你的例子是:

from django.shortcuts import render_to_response
from django.template import Template, Context
from django.utils.safestring import mark_safe
from string import letters
def home(request):
    t = Template("""<ul>
                        {% for key, value in d.items %}
                            <li>{{ key }}: {{ value }}</li>
                        {% endfor %}
                    </ul>""")
    c = Context({'d': {k: v for v, k in enumerate(letters)}})
    return render_to_response('home.html', {'t': mark_safe(t.render(c))})

然后,在 home.html 中,使用{{ t }}

于 2013-01-11T13:37:56.463 回答
1

您应该渲染您的子模板,然后将其放在home.html模板的上下文中(如t本例所示)。这是我以前用于递归模板的方法。

主页.html

<html>
<head>
    <title>Django tests</title>
</head>
<body>
    {{ t }}
</body>
</html>

视图.py

from django.shortcuts import render_to_response
from django.template import Template, Context
from string import letters

def home(request):
    t = Template("""<ul>
                        {% for key, value in d.items %}
                            <li>{{ key }}: {{ value }}</li>
                        {% endfor %}
                    </ul>""")
    d = {k: v for v, k in enumerate(letters)}
    t_rendered = t.render(Context({'d': d}))
    return render_to_response('home.html',
                              {'t': t_rendered})

请注意,您可以通过在视图之外创建子模板来缓存子模板,这样就不会在每次请求时都创建它。您可以使用loader将子模板保存在模板文件中。但是,在您重新启动服务器之前,更改不会反映出来。

from django.shortcuts import render_to_response
from django.template import Template, Context, loader
from string import letters

t = loader.get_template('subtemplate.html')

def home(request):
    d = {k: v for v, k in enumerate(letters)}
    t_rendered = t.render(Context({'d': d}))
    return render_to_response('home.html',
                              {'t': t_rendered})    
于 2013-01-11T23:44:08.047 回答
1

你应该把你的包含模板放在它自己的文件中

包括.html:

<ul>
    {% for key, value in d.items %}
        <li>{{ key }}: {{ value }}</li>
    {% endfor %}
</ul>

主页.html:

<html>
    <head>
        <title>Django tests</title>
    </head>
    <body>
        {% include 'include.html' with d=d %}
    </body>
</html>

然后你的观点变成:

def home(request):
    d = {k: v for v, k in enumerate(letters)}
    return render_to_response('home.html', {'d':d})
于 2013-01-04T15:18:40.327 回答
0

我相信render_to_response是一种快捷操作。我不认为它需要一个模板作为第二个参数,而是一个上下文

return render_to_response('home.html', {'d': d,})

<html>
<head>
    <title>Django tests</title>

</head>
<body>

<ul>
   {% for key, value in d.items %}
     <li>{{ key }}: {{ value }}
   {% endfor %}
</ul>

</body>
</html>

您可以在模板目录中创建一个列表模板并将其包含在您的模板中 https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#include 看起来包含只需要一个模板名称而不是动态模板

于 2013-01-04T15:16:27.587 回答