gpt4 book ai didi

python - django - 使用不同的基本模板渲染任何网址

转载 作者:太空宇宙 更新时间:2023-11-03 18:27:06 25 4
gpt4 key购买 nike

我希望能够使用不同的基本模板渲染项目中的部分或全部 View 。换句话说,对于 url /some/view 我希望能够拥有 /inline/some/view 并让它呈现相同的内容,但使用不同的基本模板。

修改每个 View 以接受不同的模板不是一个选项,因为我想在项目中的所有应用程序中应用此行为,包括诸如 django.contrib.auth 之类的内容。

到目前为止,我在 urls.py 中:

url("^inline/(?P<uri>.*)", format.inline, name='inline'),

以及 View ,format.py:

from django.core.urlresolvers import resolve

def inline(request, uri=''):

# get the view that would normally handle this request
view, args, kwargs = resolve('/' + uri)

# call the view
kwargs['request'] = request
template_response = view(*args, **kwargs)

# ...now what?

我不知道从这里该去哪里。我可以在调用 view() 之前修改整个模板链,以便 template_response.render() 做正确的事情吗?

也许我完全不同意这种方法,应该考虑中间件解决方案,但我很喜欢这种关闭 URL 的行为,因为稍后向内容人员解释会很容易。

更新

我能够达到我想要的效果,但执行上却严重缺乏。这是我所做的:

  • 将我希望内联的 View 模板复制到 templates/inline/
  • {% extends base.html %} 替换为 {% extends inline/base.html %}
  • 因此修改了 View :

    from django.core.urlresolvers import resolve

    def inline(request, uri=''):

    # get the view that would normally handle this request
    view, args, kwargs = resolve('/' + uri)

    # call the view
    kwargs['request'] = request
    template_response = view(*args, **kwargs)
    response.template_name = os.path.join('inline', response.template_name)
    return response

我不喜欢这个解决方案,因为它需要管理这些内联模板,每当项目中的应用程序发生变化时就需要替换/更新这些模板,等等。我仍然非常喜欢更清洁的解决方案。

更新 2:解决方案

chris-wesseling 100%正确;自定义模板加载器正是我所需要的。为了后代,这是我的实现。

应用程序/loaders.py:

from django.conf import settings
from django.template.loader import BaseLoader
from django.template.base import TemplateDoesNotExist
import os


class BaseTemplateOverrideLoader(BaseLoader):
"""
Load templates from a specified subdirectory in the current app's directory.
"""
subdir = 'templates'

def load_template_source(self, template_name, template_dirs=None):

template_dir = os.path.join(
os.path.dirname(os.path.realpath(__file__)),
self.subdir
)

try:
t = os.path.join(template_dir, template_name)
with open(t, 'rb') as fp:
return (fp.read().decode(settings.FILE_CHARSET), template_dir)
except IOError:
pass
raise TemplateDoesNotExist(template_name)


class InlineTemplateLoader(BaseTemplateOverrideLoader):
"""
Override the location of base.html for inline views.
"""
is_usable = True
subdir = 'templates/inline'

# ... other custom override classes here ....

app/views/inline.py:

from django.conf import settings
from django.core.urlresolvers import resolve
from django.template import loader


def default(request, slug=None):

view, args, kwargs = resolve('/' + slug)

old_loaders = settings.TEMPLATE_LOADERS

# Temporarily insert the inline template loader into TEMPLATE_LOADERS;
# we must also force BaseLoader to reload all templates loaders since
# they are cached at compile time.
settings.TEMPLATE_LOADERS = ('app.loaders.InlineTemplateLoader', ) + \
settings.TEMPLATE_LOADERS
loader.template_source_loaders = None

# now call the original view that handles this request
kwargs['request'] = request
response = view(*args, **kwargs)
response_string = response.render()

# restore the template loaders to their original condition
settings.TEMPLATE_LOADERS = old_loaders
loader.template_source_loaders = None

return response_string

app/templates/inline/base.html:

{% comment %}
inline/base.html
-- render just the main content without any styles etc,
for loading as inline content via ajax or whatever.
{% endcomment %}
{% block main %}{% endblock %}

最佳答案

您可以实现自己的TemplateLoader并将其设置在您的settings.TEMPLATE_LOADERS中。你可以看看这个similar question了解您正在尝试做的事情的方法。

基本上,您正在寻找的是一种从不同位置加载 base.html 的方法。

关于python - django - 使用不同的基本模板渲染任何网址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22969575/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com