You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django使用template tag按likes排序博客文章出现重复条目问题

问题根本原因

你在对多对多字段likes直接排序时,Django ORM会自动对关联的点赞表执行JOIN操作,每一条点赞记录都会对应一行查询结果,所以有N个赞的帖子就会在结果中重复出现N次。你之前直接加distinct()无效,是因为排序的字段是多对多关联的likes,查询结果每一行的关联字段值都不同,distinct()无法识别为同一帖子,必须先把点赞数聚合成单个字段再排序,才能保证每个帖子只出现一次。


解决方案

不推荐把数据查询逻辑放到模板标签中处理,优先在视图层完成排序逻辑,符合Django MTV设计规范:

  1. 修改views.py的查询逻辑,用annotate统计点赞数后再排序:
from django.db.models import Count

def posts(request):
    # 按点赞数升序排序要降序的话把'likes_count'改成'-likes_count'
    posts = BlogPost.objects.filter(user=request.user)\
                .annotate(likes_count=Count('likes'))\
                .order_by('likes_count')
    context = {'posts': posts}
    return render(request, 'posts.html', context)
  1. 删掉模板中的排序过滤器,直接遍历即可:
{% load template_tags %}

{% block content %}
{% for post in posts %}
{{post.title}}
{% endfor %}
{% endblock content %}

如果确实需要保留模板标签动态排序的能力,可以修改模板标签逻辑:

from django import template
from django.db.models import Count

register = template.Library()

@register.filter
def sort_by_likes(queryset, order='asc'):
    order_prefix = '-' if order == 'desc' else ''
    return queryset.annotate(likes_count=Count('likes'))\
                   .order_by(f'{order_prefix}likes_count')

模板调用示例:

{% for post in posts|sort_by_likes:'desc' %}
{{post.title}}
{% endfor %}

内容的提问来源于stack exchange,提问作者Van

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:54:07