在另一个页面中嵌入一个可选的Django应用,如果该应用存在的话



我们在多个站点安装了一个Django项目。在其中一些页面上,还会有一个应用程序产生一个状态框,应该显示在首页上。什么是正确的方式,让它显示,如果应用程序恰好安装。如果应用程序不存在,那么应该不显示任何内容。

我想我可以通过让状态应用程序扩展主索引页来实现:

{% extends "mainproject/index.html" %}
{% block statusboxplaceholder %}
<div> status here </div>
{% endblock %}

这是正确的、习惯的方法吗?为了添加一点内容而扩展整个首页似乎有点违反直觉。

编辑:此外,我如何管理的事实,我的应用程序将想要定义自己的"索引"页面,应该优先显示在项目范围内的"索引"页面?显然,我不想在项目的urls.py中硬编码对它的引用。我是否创建一个特定于部署的url .py,它指的是在该部署中安装的特定应用程序?如果是这样,是不是重复INSTALLED_APPS中的信息,因此违反DRY?

虽然我不认为您的方法有问题,但我认为通用模板标记将提供最大的灵活性,特别是如果您想将此功能扩展到以后可能安装的其他应用程序。

你的基模板加载了一个通用的"boxes"标签。在标签的源代码中,您可以根据该特定实例安装的应用程序呈现任何您想要的内容。所以你可以有一组默认的应用程序来渲染盒子,或者最终用户可以自定义哪些应用程序应该渲染盒子。

在你的设置、配置甚至标签中,你可以为每个应用确定要渲染的模板。

假设每个应用程序在app/templates目录下都有它的模板-这个psuedo应该可以让你开始(这是未经测试的):

from django.conf import settings
from django import template
register = template.Library()
class GenericBox(template.Node):
   def __init__(self, app):
      self.app = app
   def render(self, context):
      if self.app not in settings.INSTALLED_APPS:
         return '' # if the app is not installed
      # Here you would probably do a lookup against
      # django.settings or some other lookup to find out which
      # template to load based on the app.
      t = template.loader.get_template('some_template.html') # (or load from var)
      c = template.RequestContext(context,{'var':'value'}) # optional
      return t.render(c)    
@register.tag(name='custom_box', takes_context=True, context_class=RequestContext)
def box(parser, token):
    parts = token.split_contents()
    if len(parts) != 2:
        parts[1] = 'default_app' # is the default app that will be rendered.
    return GenericBox(parts[1])

最新更新