如何在django模板中执行查询过滤
-
03-07-2019 - |
题
我需要在django模板中执行过滤查询,以获得一组与视图中的python代码等效的对象:
queryset = Modelclass.objects.filter(somekey=foo)
在我的模板中,我想做
{% for object in data.somekey_set.FILTER %}
但我似乎无法找到如何写FILTER。
解决方案
你不能这样做,这是设计的。 Django框架作者希望严格分离表示代码和数据逻辑。过滤模型是数据逻辑,输出HTML是表示逻辑。
所以你有几个选择。最简单的方法是进行过滤,然后将结果传递给render_to_response
。或者您可以在模型中编写一个方法,以便您可以说{% for object in data.filtered_set %}
。最后,您可以编写自己的模板标记,但在这种特定情况下,我会建议您反对。
其他提示
我只需添加一个额外的模板标签:
@register.filter
def in_category(things, category):
return things.filter(category=category)
然后我可以做:
{% for category in categories %}
{% for thing in things|in_category:category %}
{{ thing }}
{% endfor %}
{% endfor %}
我经常遇到这个问题并经常使用<!>“添加方法<!>”;解。但是,确实存在<!>添加方法<!>的情况。或<!> quot;在视图中计算它<!>不工作(或不工作)。例如。当您缓存模板片段并需要一些非平凡的DB计算来生成它时。除非您需要,否则您不希望执行数据库工作,但在深入了解模板逻辑之前,您不会知道是否需要。
其他一些可能的解决方案:
-
使用{%expr <!> lt; expression <!> gt; as <!> lt; var_name <!> gt; %}模板标记位于 http://www.djangosnippets.org/snippets/9/ 表达式是任何合法的Python表达式,模板的Context作为本地范围。
-
更改模板处理器。 Jinja2( http://jinja.pocoo.org/2/ )的语法几乎与Django模板语言,但具有完整的Python功能。它也更快。您可以批量执行此操作,或者可以将其使用限制为您正在使用的模板,但使用Django的<!>更安全<!>设计师维护页面的模板。
醇>
这可以通过赋值标记来解决:
from django import template
register = template.Library()
@register.assignment_tag
def query(qs, **kwargs):
""" template tag which allows queryset filtering. Usage:
{% query books author=author as mybooks %}
{% for book in mybooks %}
...
{% endfor %}
"""
return qs.filter(**kwargs)
另一个选择是,如果您有一个总是想要应用的过滤器,则添加自定义管理器总是将过滤器应用于返回的结果。
一个很好的例子就是一个Event
模型,对于你在模型上做的90%的查询,你会想要像Event.objects.filter(date__gte=now)
这样的东西,即你通常对Events
感兴趣即将到来的。这看起来像是:
class EventManager(models.Manager):
def get_query_set(self):
now = datetime.now()
return super(EventManager,self).get_query_set().filter(date__gte=now)
在模型中:
class Event(models.Model):
...
objects = EventManager()
但同样,这对于在<=>模型上完成的所有默认查询应用相同的过滤器,因此不像上面介绍的某些技术那样灵活。