【问题标题】:order_by creates duplicate entriesorder_by 创建重复条目
【发布时间】:2017-08-27 16:50:03
【问题描述】:

我有 4 个模型类:User、Stack、Article 和 Rating。用户可以创建堆栈、添加文章、将它们放在堆栈上、评价文章并共享堆栈。 我想获取特定堆栈的所有文章的查询集(由 pk 获取)并按当前用户评分排序。如果堆栈是共享的并且一篇文章被另一个用户评分,我的查询会导致我的 QuerySet 中出现重复条目​​,因此一篇文章存在两次评分对象:

qs = stack.article_set.all().order_by("ratings__rating", "-pk")

型号:

class Rating(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name='ratings'
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name='ratings'
    )
    rating = models.IntegerField()


class Stack(models.Model):
    title = models.CharField(null=True, max_length=100)

    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)


class Article(models.Model):
    stack = models.ForeignKey(Stack, null=True, blank=True, on_delete=models.CASCADE)

    text = models.TextField(null=True, blank=True)

我怎样才能得到没有重复的有序 QuerySet,只是按 request.user 评级排序。

更新

我现在要做的是查询两次。一次获取已评级的文章对象,第二次获取未排序的当前未评级的文章对象。

    context['rated_articles'] = deck.article_set.filter(
        ratings__user__exact=self.request.user
        ).order_by("ratings__rating", "-pk")

    context['not_rated_articles'] = deck.article_set.all().exclude(
        ratings__user__exact=self.request.user
    )

【问题讨论】:

    标签: django django-views django-queryset


    【解决方案1】:

    您应该能够在订购之前根据堆栈所有者过滤文章集

    user = stack.owner
    stack.article_set.filter(rating__user__exact=user).order_by("ratings__rating", "-pk")
    

    【讨论】:

    • 不,但我现在试过了,打电话给stack.article_set.all().order_by("ratings__rating", "-pk").distict() 只会删掉其他用户评分相同的文章。如果其他用户的评分与当前用户不同,则不会区分对象。
    • 我明白你的意思。我认为在尝试按评级排序时,您的查询集中可能总是有重复项,因为一篇文章可以有多个评级。也许只是返回文章查询集 unordered,然后编写一些代码手动按评级对其进行排序?但是,当一篇文章有​​多个评分时,您会遇到选择使用哪个评分的问题
    • 尝试将 'article_id' 作为参数传递给 distinct
    • 返回 DISTINCT ON fields is not supported by this database backend 因为我使用 MySQL 而不是 PostgreSQL。但我认为这样它不会总是区分正确的对象。它只检查article_id 的重复项,而不检查评级对象是否来自request.user
    • 这种方式可以正确过滤,但一个限制是我需要获取所有文章,即使它们当前没有被 request.user 评级。现在我通过排除已评级的对象来执行另一个查询。
    猜你喜欢
    • 1970-01-01
    • 2018-08-15
    • 2016-03-30
    • 2020-09-26
    • 1970-01-01
    • 2015-02-13
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多