【问题标题】:How to put generic view code in a Django base template如何将通用视图代码放入 Django 基本模板中
【发布时间】:2014-09-16 04:17:12
【问题描述】:
我有一个简单的 Django 站点,其中包含一个基本模板,然后是特定页面的各种模板。这适用于应用品牌、样式等。
我的网站在概念上类似于 JIRA,其中每个视图都需要通过一个名为 project 的总体变量来通知,用户可以从菜单栏中的下拉列表中进行选择。
菜单栏位于基本模板中。下拉列表将由数据库查询填充(获取登录用户关联的所有项目)。如何进行该查询并将数据发送到基本模板?我宁愿不要将相同的查询附加到使用模板的每个视图!
【问题讨论】:
标签:
django
django-templates
django-views
【解决方案1】:
我决定使用模板标签。操作方法如下:
- 在相关应用文件夹下,创建
templatetags/文件夹。
- 在
templatetags 文件夹中,创建一个名为__init__.py 的空文件
- 在
templatetags 文件夹中,为您的标签创建一个文件。我们称之为menu_items.py
-
这将是一个包含标记,这意味着它还需要一个模板文件。像这样设置它:
from django import template
from relevant_app import ItemToDisplay
register = template.Library()
@register.inclusion_tag('relevant_app/menu_items.html', takes_context=True)
def menu_items(context):
return {'items': ItemsToDisplay.objects.all()}
-
在相关模板文件夹中创建menu_items.html 模板文件(在本例中,在relevant_app 项目中,它将是templates\relevant_app):
{% for item in items %}
<li><a href="{% url items item=item %}">{{ item.item_name }}</a></li>
{% endfor %}
-
将模板标签添加到主模板中:
{% load menu_items %}
{# ... #}
{% menu_items %}
这似乎是 Django 执行此操作的方式。标签类型看起来有点繁琐。我很难让他们都接受上下文,所以我现在只使用inclusion_tag。
【解决方案2】:
最近,我一直在将每个页面上调用的查询存储在中间件对象中,并将响应存储在请求对象中。
例如
# Advanced Queries
from django.db.models import Q # If you need if ( not required )
from django.conf import settings # Application Configuration
class NameThisClass(object):
def process_request(self, request):
"""
Do some processing to get information from the url to load the correct project information.
"""
request.projects = {}
request.projects["menu"] = Menu.objects.filter(params)
然后您可以在每个模板中访问它,并调用而无需从
模块视图。
像这样
{{ request.menu }}
注意:这就像在需要时运行对象的传统 for 循环一样。
您必须先发现才能从 URL 中获取正确的信息,但是
在某些情况下,这确实是微不足道的。
注意事项:
确保在 settings.py 文件中设置了上下文处理器。
以及在 settings.py 中的中间件字典中添加中间件位置
一切顺利