如果存在可选的Django应用程序,请在另一个页面中嵌入该应用程序 [英] Embed an optional Django application in another page, if that app is present

查看:54
本文介绍了如果存在可选的Django应用程序,请在另一个页面中嵌入该应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We have a Django project installed at multiple sites. At a couple of them, there will also be an app which produces a status box which should show on the front page, say. What's the right way to have it show up, if the app happens to be installed. If the app is not present, then nothing should display.

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

I think I could do it by having the status app extend the main index page:

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

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

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

Is that the right, idiomatic approach? It seems slightly counterintuitive to extend the entire front page just to add a little bit of content.

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

Also, how do I manage the fact that my app will want to define its own "index" page, that should be shown in preference to the project-wide "index" page? I obviously don't want to hard-code a reference to it in the project's urls.py. Do I create a deployment-specific urls.py which refers to specific apps that are installed at that deployment? And if so, isn't that repeating the information in INSTALLED_APPS, and hence violating DRY?

推荐答案

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

Although I don't see a problem with your approach, but I think a generic template tag would provide the most flexibilty, especially if you want to extend this ability to other applications that you might install later.

您的基本模板会加载通用的框"标签.然后,您可以在标签的来源中根据该特定实例的已安装应用程序呈现所需的任何内容.因此,您可以具有一组默认应用程序来为其渲染框,​​或者最终用户可以自定义应渲染哪些应用程序的框.

Your base template loads a generic "boxes" tag. In the tag's source, you can then render whatever you want based on the installed apps for that particular instance. So you can have a set of default apps to render boxes for, or the end user can customize which apps should have boxes rendered.

在设置,配置甚至标签本身中,您可以标识要为每个应用程序块渲染的模板.

In your settings, configuration or even in the tag itself, you can identify the template to render for the block per app.

假设每个应用程序在 app/templates 目录中都有其模板-该伪指令应该可以帮助您(未经测试):

Assuming that each app has its templates in app/templates directory - this psuedo should get you going (this is untested):

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])

这篇关于如果存在可选的Django应用程序,请在另一个页面中嵌入该应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆