Embed an optional Django application in another page, if that app is present

泪湿孤枕 提交于 2019-12-11 12:45:32

问题


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.

EDIT: 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?


回答1:


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.

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


来源:https://stackoverflow.com/questions/8557479/embed-an-optional-django-application-in-another-page-if-that-app-is-present

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!