您知道在 Django 模板中增加值的自定义标签吗?
严格的MVC的一件非常烦人的事情是你可以在模板中进行最小的处理。虽然这通常是一个很好的做法,但在这种情况下它会妨碍:
- 我在许多对象的查询集上创建一个 for 循环并显示一些属性;
- 属性就是属性,进行繁重的处理(我不想触发它们两次)。
- 最后我需要显示这些属性的总值。
我现在必须在视图中进行一次求和,然后重新循环(并再次调用属性)来显示。我可以通过在视图中循环一次并缓存结果来改进这一点,但随后我会获得更多代码来绕过此限制,并且我会使用更多内存。
在项目的现阶段,这并不是什么大问题。性能根本还不是问题。但我真的很想知道是否有解决方案。
我最好的选择是编写一个模板标签来完成这项工作,但这真是一件苦差事:-) 你知道有人已经这样做了吗?
EG:
理想情况下,它应该是这样的:
{% for object in object_list %}
- {% sum_in_and_print object.property total %}
{% endfor %}
total {{ total }}
会显示:
- 2
- 3
- 1
total 6
One very annoying thing with strict MVC is that you can make the smallest processing in template. While it's usually a good practice, in this case it gets in the way:
- I make a for loop on a queryset of a lot of objects and display some attributes;
- Attributes are properties, making heavy processing (I don't want to trigger them twice).
- At the end I need to display a total of the value of these attributes.
I now I have to do the sum once in the view, then reloop (and call the properties again) to display. I can improve that by loopring once in the view and caching the results, but then I get more code just to bypass this limitations, and I use more memory.
At this stage of the project, it's not THAT a big deal. Performance is not the issue yet at all. But I really like to know is there is a solution for this.
My best bet is to write a template tag that does the job, but it's such a chore :-) Do you know somebody that would have done that already?
E.G:
Ideal, it sould be something like:
{% for object in object_list %}
- {% sum_in_and_print object.property total %}
{% endfor %}
total {{ total }}
that would display:
- 2
- 3
- 1
total 6
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我不明白这是一件苦差事。检查目标变量是否在上下文中,如果不在,则使用列表中第一个元素的类的空构造对象对其进行初始化,然后进行累加。
I don't see how it's a chore. Check if the destination variable is in the context, and if not, initialize it with an empty-constructed object of the class of the first element in the list, then accumulate.
作为在视图或模板中计算总和的替代方法,如何使用 QuerySet.Annotate(total_x=Sum('x')) 让数据库负责计算?
旁白:我认为,在没有明显答案的情况下,尝试解决实际问题有时不需要回答直接问题。
As an alternative to calculating the sum in a view or template, what about QuerySet.Annotate(total_x=Sum('x')), to have the database take care of the calculations?
Aside: I believe trying to solve the actual problem sometimes warrants not answering the direct question when there is not an obvious answer.
我很难写得漂亮。您必须注意评估顺序是否正确(总和可能会显示在数据上方)。您可以有许多总结部分(也许还有数据)。您可能需要以下结构:
编辑:
此外,您将很难解析多层结构:
I'ts quite hard tag to write nicely. You will have to take care if evaluation order is ok (sum may be displayed above data). That you can have many sumup sections (maybe data too). You will need probably following structure:
EDIT:
Also you will have hard times, to parse multilevel structure:
我不知道你正在开发什么项目,但如果你已经要求用户有JavaScript,你可以检查 jQuery.calculation 插件。这是一个很好的工具,可以将所有愚蠢的计算转移到客户端。
I don't know what project your're developing, but if you already require users to have JavaScript, you may check jQuery.calculation plugin. This is a great tool to shift all dumb calculations to the client side.
研究一下不同的模板系统,比如 Mako。 Mako 特别允许完整的 python 代码在模板中运行。
Look into a different templating system like Mako. Mako especially allows full python code to run within the template.
您没有在视图中执行此操作是否有令人信服的原因?
还有什么比这更简单的:
即使您的目标是使用泛型,您也可以随时将其包装在视图函数中。
让我补充一点,我认为您特别想要的功能:输出变量并将其添加到某个任意变量 - 是一个非常独特的功能,您绝对需要为其编写自己的模板标记。
幸运的是,这非常简单。
更新
所以你可以尝试这个:
你在视图中处理它一次,然后当你在模板中输出它时,它是一个字典,字典中的所有内容都已经处理过。
Is there a compelling reason you're not doing this in the view?
What could be easier than:
Even if your goal is to use generics, you can always wrap it in a view function.
Let me add that I think the functionality you specifically want: to output a variable and add it to some arbitrary variable -- is such a unique one that absolutely you'll want to write your own template tag for it.
Fortunately, this is very easy.
Update
So you could try this instead:
You process it once, in the view, then when you output it in the template, it's a dictionary, with everything in the dictionary already processed.