1

我们在多个站点安装了一个 Django 项目。在其中的几个中,还会有一个应用程序生成一个状态框,该状态框应该显示在首页上,比如说。如果碰巧安装了应用程序,那么显示它的正确方法是什么。如果应用程序不存在,则不应显示任何内容。

我想我可以通过让状态应用程序扩展主索引页面来做到这一点:

{% extends "mainproject/index.html" %}

{% block statusboxplaceholder %}
<div> status here </div>
{% endblock %}

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

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

4

1 回答 1

2

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

您的基本模板会加载一个通用的“boxes”标签。在标签的源代码中,您可以根据为该特定实例安装的应用程序呈现您想要的任何内容。因此,您可以拥有一组默认应用程序来渲染框,或者最终用户可以自定义哪些应用程序应该渲染框。

在您的设置、配置甚至标签本身中,您可以确定要为每个应用程序块呈现的模板。

假设每个应用程序在app/templates目录中都有它的模板 - 这个伪程序应该让你继续前进(这是未经测试的):

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])
于 2011-12-19T06:18:06.327 回答