【问题标题】:Returning Dictionary From templatetags and Printing in template从模板标签返回字典并在模板中打印
【发布时间】:2019-11-10 07:02:20
【问题描述】:

我正在尝试为每个问题返回投票最多的答案。我还想发送该答案的额外信息,例如 vote 和 id

打印一个值很容易,但对于多个值,我必须返回字典。那么如何返回字典并打印模板中的所有值。

from django import template
register = template.Library()

    @register.simple_tag
    def getmostvotedanswer(answers):
        answer = answers.order_by('-vote')[0]
        answer_info = {
            'answer':answer.answer,
            'vote':answer.vote,
            'id':answer.id
        }
        return answer_info

index.html

<p class="small text-muted ">{% getmostvotedanswer question.answer_set.all %}</p>
输出
{'answer': 'THIS IS ANSWER THIS IS ANSWER THIS IS ANSWER THIS IS ANSWER THIS IS ANSWER', 'vote': 7, 'id': 1}

我可以为三个值调用 template_tag 3 次。

但我不想一次又一次地调用 templatetag 我认为它会影响性能。

view.py

def index(request):
    questions = Question.objects.all()
    context = {
        'questions':questions
    }
    return render(request,'index.html',context=context)

编辑 -> 添加 view.py

【问题讨论】:

  • 为什么要使用模板标签?在将其发送到模板之前,在视图上发送烹饪数据更容易且可调试。
  • @daniherrera 这不可能,因为我在模板中做反向关系。对于一个问题可以有多个答案,但在主页上我只想显示投票最高的答案。这就是我发送问题的原因使用 View 并使用 templatetag 获得最高票数的答案
  • 什么是“最高票”? 3? 10 点?
  • @daniherrera 投票最多的先生
  • 我的回答解决了你的问题吗?

标签: django templates templatetags


【解决方案1】:

实现它的最简单、可调试、最佳性能和测试友好的方法是在视图上烹饪数据,而不是编写自定义模板标签。需要windows函数才能得到每个问题的第一个答案:

from django.db.models import F, Window
from django.db.models.functions.window import FirstValue

def index(request):

    #q_and_a_ids = [ (id question, id most voted answer), (... ]
    q_and_a_ids = (
      Question
      .objects
      .annotate(
        most_voted_id=Window(
          expression=FirstValue('answer__id'),
          partition_by=['id'],
          order_by=F('answer__vote').desc()
        )
       )
      .distinct()
      .values_list( 'id', 'most_voted_id')
    )

    answers_ids = set( [ a_id for (_,a_id) in q_and_a_ids] )

    questions_dict = Question.objects.in_bulk()
    answers_dict = Answers.objects.filter(pk__in=answers_ids).in_bulk()

    #q_and_a = [ { 'q':question, 'a':most voted answer}, { ... ]
    q_and_a = [ {'q': questions_dict[q_id],
                 'a': answers_dict.get(a_id) } 
                 for (q_id,a_id) in q_and_a_ids ]

    context = {
        'questions_and_answers': q_and_a
    }
    return render(request,'index.html',context=context)

【讨论】:

    猜你喜欢
    • 2017-08-19
    • 1970-01-01
    • 2013-05-06
    • 2019-01-17
    • 2014-12-06
    • 2016-05-26
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    相关资源
    最近更新 更多