【问题标题】:Django model query selecting related items and excluding current objectDjango模型查询选择相关项目并排除当前对象
【发布时间】:2021-08-14 07:08:53
【问题描述】:

我正在使用 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 中EXCLUDE 失败 - 尽管我在返回的 QuerySet 上明确 调用 exclude()

为什么会这样?

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

【问题讨论】:

  • 你是如何检索到article_object的。
  • @WillemVanOnsem sn-p 充实了一些

标签: django django-models django-queryset


【解决方案1】:

您应该使用.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()

【讨论】:

  • 别忘了 import Count :from django.db.models import Count
  • @WillemVanOnsem:我注意到您首先调用了exclude() - 链接方法的顺序重要吗? (即这有关系吗?)-另外,您能否解释一下为什么我们必须在这里使用Count?我不明白为什么我们需要在这里使用注释。谢谢
  • @HomunculusReticulli:您想确定共有标签的数量,因此为了提供具有最常见标签的文章,我们确定这一点,并按该数量排序。它还可以防止 LEFT OUTER JOIN 没有 GROUPBY 导致 same 文章在查询集中多次出现,因此我们可以消除 @987654327 @.
  • @WillemVanOnsem 感谢您的解释。我现在明白了。但是,我只是运行查询,它仍然在返回的查询集中包含article_object! ://
  • @WillemVanOnsem 对不起,我的错。我必须重新启动服务器才能进行更改 - 似乎。现在好像都是tickety-boo了。
猜你喜欢
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-13
  • 1970-01-01
  • 1970-01-01
  • 2018-10-06
  • 2020-07-16
相关资源
最近更新 更多