【问题标题】:Custom Template Tag Queryset Not Returning Anything自定义模板标记查询集不返回任何内容
【发布时间】:2016-07-28 02:54:54
【问题描述】:

我正在尝试实现一个显示最近创建的 5 个事件的功能。我决定用 Django 自定义模板标签来实现它(如果这不是最好的方法,请告诉我)。到目前为止我所拥有的是:

在 event_search.html 中(除其他外):

{% extends 'base.html' %}
{% load eventSearch_extras %}
<p>count: {{ recents.count }}</p>
<ul>
{% for e in recents %}
    <li> {{e.title}} </li>
{% empty %}
    <li> No recent events </li>
{% endfor %}
</ul>

在 eventSearch_extra.py 中:

from django import template
from eventSearch.models import Event

register = template.Library()

@register.inclusion_tag('eventSearch/event_search.html')
def mostrecentevents():
    """Returns most 5 most recent events"""
    recents = Event.objects.order_by('-created_time')[:5]
    return {'recents': recents}

我的问题是查询集“最近”似乎返回空模板。 'count:' 不显示任何内容,for 循环默认为 'No recent events'。

【问题讨论】:

  • 这看起来是一种极其复杂的做事方式……你只是想在每个页面上显示这些“最近”吗?
  • 不,只是搜索页面。最好的方法是什么?
  • 只是将它们包含在搜索页面视图的上下文数据中?我不确定我是否在这里遗漏了什么..

标签: django django-models django-templates django-views


【解决方案1】:

您已经加载了inclusion tag function,,但没有加载单个标签,因此永远不会调用填充该信息的代码;它的布局也有些奇怪,所以你从错误的地方打电话。

主模板调用包含标签使用:

{% load eventSearch_extras %}

你可以通过调用来包含实际的标签

{{mostrecentevents}} 

mostrecentevents 启动并运行代码,解析 event_search.html 的 html 并将其放入主模板中。刚才您的代码设置方式,您将从其自己的 HTML 调用包含标记。

主模板> {% load inclusion_tags %} {{ actual_tag }}

例如,我有一个餐厅模板。在该模板中是以下代码:

{% load restaurant_menu %}  <!--main inclusion tag .py file) --> 
{% menu %}  <!-- the actual tag code you want to run --> 

在 restaurant_menu.py 我有以下内容(删除了其他不相关的内容):

@register.inclusion_tag('core/_menu.html', takes_context=True)
def menu(context):
    filtered =  context['filtered']
    from core.models import MenuItem, FoodProfile, Ingredient, Recipe
    if filtered:
        restaurant = context['restaurant'].id
        filtered_menu = #stuff here 
        restaurant_menu = filtered_menu
    else:
        restaurant_menu = MenuItem.objects.filter(restaurant__pk=context['restaurant'].id)
    return {"restaurant_menu": restaurant_menu,
            "number_of_menu_items": restaurant_menu.count(),
            "filtered": filtered}

和 _menu.html 页面(下划线让我知道它是一个片段):

<ul>
    {% for item in course.list %}
        <li>
{{ item.number|floatformat:0 }}  {{ item.name }} {{ item.description }} {{ item.price  }} </li>
</li>{% endfor %}
{% endfor %}
</ul>

【讨论】:

    【解决方案2】:

    inclusion tag 用于渲染另一个模板。创建一个呈现event_search.html 的包含标记,然后在event_search.html 本身内部调用该模板标记是没有意义的。请注意,您实际上并没有使用模板标签({% mostrecentevents %}),您所做的只是加载模板标签库。

    改用simple tag 会更容易。

    @register.simple_tag
    def mostrecentevents():
        """Returns most 5 most recent events"""
        recents = Event.objects.order_by('-created_time')[:5]
        return recents
    

    然后在你的模板中你可以这样做:

    {% load eventSearch_extras %}
    {% mostrecentevents as recents %}
    

    这会将模板标签的结果加载到变量recents中,您现在可以这样做:

    <p>count: {{ recents.count }}</p>
    <ul>
    {% for e in recents %}
        <li> {{e.title}} </li>
    {% empty %}
        <li> No recent events </li>
    {% endfor %}
    </ul>
    

    请注意,您只能在 Django 1.9+ 中使用带有简单标签的 as recents 语法。对于早期版本,您可以改用assignment tag

    【讨论】:

    • 你太棒了!它节省了我的时间。但是我在django文档上没有看到这个,你在哪里看到的?非常感谢..
    • @BurakÖztürk 我不确定您在寻找什么链接...答案已经多次链接到 Django 文档。
    • 这与我链接到的页面相同(但针对 1.9 而不是 1.11,因为几年前我写了这个答案)。
    猜你喜欢
    • 2014-10-17
    • 2022-06-21
    • 2012-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    相关资源
    最近更新 更多