由于Django不鼓励在模板中向函数传递参数,那么有什么推荐的做法呢?

5 投票
2 回答
804 浏览
提问于 2025-04-16 14:14

我明白在Django中,模板语言被故意简化,以防止在显示代码中进行过多的计算。这意味着,理想情况下,用户在需要计算的情况下,总会有更合适的替代方案。要么是一个可以完成任务的标签或过滤器,要么是在视图中有一些简单的处理。那些不符合这些情况的麻烦,应该是比较少见的。

但是我发现一个常见的情况相当麻烦,要么Django有更好的解决办法我没想到,要么他们应该在未来的版本中考虑调整一下模板中的计算限制(就像他们之前对if语句参数所做的那样):

我有一组项目的查询集。我需要以某种方式展示这些项目,但我展示的内容不仅取决于对象的状态,还取决于其他独立的因素(通常是哪个用户登录了)。所以在模型中添加一个函数并没有帮助。

到目前为止,我的做法是把查询集转成一个列表或树结构(根据任务的不同),然后给每个项目添加一个“view_extra”属性。view_extra是一个字典,我通常在里面放一些依赖于登录用户等信息的值。除了麻烦之外,这样做还破坏了查询集的懒加载特性。我想我可以进一步做一个生成器,但显然这不是Django开发者希望我们这样做的。

我可能应该多尝试查询集的注释功能,但我不知道在一些更复杂的情况下效果如何。而且在树结构或列表中的列表场景下(比如项目的查询集里面还有其他查询集需要遍历)也没有什么用。

我可以注册一个过滤器(就像这里提到的 django模板系统,调用模型中的函数),但这算不算是对过滤器的滥用呢?过滤器的目的是用来转换文本和数据,而不是作为开发者故意不希望我们使用的特定用途的替代品。

有没有什么“合适”的方法我不知道?我是不是在这里偏离了主题,认为这是Django模板系统的一个不足之处?

2 个回答

2

也许在这种情况下,使用Jinja 模板会是一个不错的选择,替代 Django 的模板系统。除了 Jinja 允许你在模板中使用一些逻辑这一重要特点外,Jinja 模板和 Django 模板几乎是一样的。

下面这段示例代码直接来自 Jinja 的文档,看起来可能正是你想要实现的东西。

{% for comment in models.comments.latest(10) %}
    ...
{% endfor %}

要将 Jinja 与 Django 集成,你可以看看Coffin

4

我不明白为什么创建一个自定义标签或过滤器会被认为是“滥用”。在我看来,这正是它们的用途,我一直都是这样使用它们的。

撰写回答