首页 > 解决方案 > Django模型查询选择相关项目并排除当前对象

问题描述

我正在使用 Django 3.2

我有一个文章模型:

from taggit.managers import TaggitManager

class Article(models.Model):
    # fields
    tags = TaggitManager()

在我看来,我尝试选择相关文章(使用标签相似度作为“距离度量”)。

这是在我的视图处理逻辑中返回相关文章的语句:

class ArticleDetailView(DetailView):
    model = Article
    pk_url_kwarg = "pk"
    slug_url_kwarg = 'slug'
    query_pk_and_slug = True
    

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)

        article_object = self.get_object()
        article_tags_array = list(set([x for x in article_object.tags.names()]))         
        related_articles = self.model.objects.filter(is_published=True, tags__name__in=article_tags_array).exclude(id=article_object.id).prefetch_related().distinct()        
   
        context["related_articles"] = related_articles

        return context

但是,此语句无法在返回的 QuerySet 中排除当前对象——尽管我明确地调用了返回的 QuerySet exclude()

为什么会这样?

如何解决此问题,以使当前对象不包含在返回的集合中?

标签: djangodjango-modelsdjango-queryset

解决方案


您应该使用.annotate(…)计算匹配标签的数量:

from django.db.models import Count

article_object = self.object
article_tags_array = article_object.tags.all()
related_articles = self.model.objects.exclude(pk=article_object.pk).filter(
    is_published=True,
    tags__in=article_tags_array
).annotate(
    matching_tags=Count('tags')
).order_by('-matching_tags').prefetch_related()

推荐阅读