【问题标题】:Aggregate related integer-field values in Django template在 Django 模板中聚合相关的整数字段值
【发布时间】:2019-12-06 00:54:26
【问题描述】:

我有一个与 Node 模型相关的模型,

class Views(models.Model):
    related_tree = models.ForeignKey(Node, on_delete=models.CASCADE, blank=True, null=True, related_name='related_views')
    views_count = models.PositiveIntegerField(null=True, blank=True, default=0)
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, blank=True, null=True)

    def __str__(self):
        return self.related_tree.name

在模板中,当我查询节点对象列表时,我想汇总每个对象的“views_count”值。

我已经在我的模板中尝试过这个

{% for tree in tree_result|slice:":14" %}
{% for view in tree.related_views.all %}

{{ view.views_count }}
{% endfor %}
{% endfor %}

我拥有当前树的所有相关 count_view 但我想做的是聚合相关字段的值并将其显示在 tree_result 的 for 循环中。

有什么建议吗?

编辑:

def ResultSearch(request, search):
    formatted_search = search.split('+$')
    filter = Q()
    cases = {}
    get_result_list = [x for x in search.split('+$') if x != '']
    for i, keyword in enumerate(get_result_list):
        filter |= Q(name__icontains=keyword)
        filter |= Q(Tags__icontains=keyword)
        cases['keyword_match_{}'.format(i)] = Case(
            When(name__icontains=keyword, then=1),
            default=Value(0),
            output_field=models.IntegerField(),
        )
    result = Node.objects.filter(
        filter,
        tree_type='root',
        published=True,
        tunisia_office=True
    ).annotate(
        **cases
    ).annotate(
        total_views=Sum('related_views__views_count'),
        num_bookmarks=Count('bookmarked_by'),
        keywords_matched=reduce(add, (F(name) for name in cases))
    ).order_by('-keywords_matched', '-num_bookmarks')

    context = {
    'searched_keyword': formatted_search,
    'result_list': result,
    } 

【问题讨论】:

    标签: django django-templates django-related-manager


    【解决方案1】:

    您应该在视图中注释您的查询集,例如:

    from django.db.models import Sum
    
    Node.objects.annotate(
        total_views=Sum('related_views__views_count')
    )

    由此查询集产生的Nodes 将有一个额外的属性.total_views,它是相关Viewsviews_count 的总和。

    在您的模板中,您可以像这样呈现:

    {% for tree in tree_result|slice:":14" %}
        {{ tree.total_views }}
    {% endfor %}

    注意:请不要模板中聚合。模板并非旨在实现业务逻辑。模板应该只包含“渲染逻辑”。通过使用注释,您将让数据库进行聚合。数据库通常经过优化以执行此类任务。

    【讨论】:

    • 感谢您的回答,问题是实际上当我将 {{ tree.total_views }} 添加到模板中时,每次我在模板中的视图计数中添加 +1 时都会增加4 个,因为实际上我有 3 个视图,在模板中是 16
    • @FarhaniWalid:您也可以在视图中更新它,例如tree.related_views.update(views_count=F('views_count')+1)。话虽如此,具有副作用的属性可能不是最好的代码设计。
    • db 方面一切似乎都很好,+1 的增量正在工作,但在渲染的模板中我有一个增量 4,我添加了整个视图,也许问题来自那里?
    • 我会接受你的回答,我会为我面临的新问题重新发布一个,无论如何谢谢
    猜你喜欢
    • 2019-10-24
    • 2016-07-23
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 2020-01-30
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多