你能制作一个返回查询集的自定义模板标签吗?如果有,怎么样? - Django

时间:2011-10-31 12:56:47

标签: django django-templates

让我们的SOians同志们这么容易(?)。

这是自定义模板标记正常工作的方式 -

模板 - >

{% block content %}

     blah blah blah

     {% custom_tag_load %}

{% endblock %}

调用custom_tag_load并返回一个字符串。我想要返回的是一个查询集,我可以像这样使用 - >

{% block content %}

     blah blah blah

     {% for x in custom_tag_load %}

          {{ x.datetime }}

     {% endfor %}

{% endblock %}

注意 - >我基本上要做的是避免通过视图传递查询集,我不确定我是否应该在我的全局上下文中存储查询集。

3 个答案:

答案 0 :(得分:6)

您可以从标记中返回任何内容,包括查询集。但是,您不能在for标记内使用标记 - 您只能在那里使用变量(或通过过滤器传递的变量)。你可以做的是让你的标签将查询集放入上下文中的变量,并在for循环中使用该变量。请参阅how to set a variable from a tag上的文档 - 尽管请注意用于执行此操作的开发版has an easier method

但是,您不应该担心将查询集放入上下文处理器。不要忘记查询集是惰性的,因此除非在模板中评估或迭代查询集,否则不会进行数据库命中。

答案 1 :(得分:4)

模板标签可以做任何你想做的事情。从伪代码中,您可以使用包含标记来完成所需的操作:

#my_tags.py
from django import template
from my_app.models import MyModel

register = template.Library()

@register.inclusion_tag('my_template.html')
def my_custom_tag():
    things = MyModel.objects.all()
    return {'things' : things}


#my_template.html
{% if things %}
    <ul>
    {% for thing in things %}
        <li>{{ thing }}</li>    
    {% empty %}
        <li>Sorry, no things yet.</li>
    {% endfor %}
    </ul>
{% endif %}


#the_view.html
{% load my_tags %}

{% my_custom_tag %}

或者,您可以编写一个自定义标记,将查询集添加到上下文中。希望能帮到你。

答案 2 :(得分:0)

我最近遇到了同样的问题,这里的大多数答案都有些过时了,但稍微翻了一下 Django 的文档,我就能够解决它。

像上面的大多数答案一样,您基本上可以使用模板标签返回任何内容,但这一切都取决于您如何注册模板标签。因此,假设您想使用模板标签返回查询集以供您希望的任何模板使用,您可以将模板标签注册为一个简单的标签,就像这样

from django import template    
from blog.models import Post
from django.template.defaulttags import register

register = template.Library()

@register.simple_tag
def get_posts():
    return Post.objects.all()

然后为了能够在你的模板中访问它,你首先需要在你的模板中加载这个文件

{% load templatetagfile %}

然后要循环,你需要在循环之前先把它赋值给一个变量

{% get_posts as posts %}
{% for post in posts %}
    {{ post.whatever }}
{% endfor %}

第一行使 get_posts 函数中的查询集可用作名为 posts 的变量,然后您可以循环遍历该变量。