【问题标题】:Django: get objects.all() with the related rows in another ManyToMany tableDjango:获取 objects.all() 以及另一个 ManyToMany 表中的相关行
【发布时间】:2017-09-26 15:10:23
【问题描述】:

我有 3 个模型:

  • django 普通用户模型
  • 作者模型
  • UserAuthor 模型被认为是前两个模型之间的多对多关系,但带有附加字段(is_follow、review)

    class Author(models.Model):
        name = models.CharField(max_length=50)
    
    class UserAuthor(models.Model):
        user = models.ForeignKey(User, on_delete=models.CASCADE)
        author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='userauthors')
        is_follow = models.BooleanField(default=0)
        review = models.TextField(max_length=500, blank=True, null=True)
    

我的问题是关于如何让所有作者在每个作者中都有一个字段,以表明经过身份验证的用户是否在关注他。

我知道我可以使用 related_name 属性,该属性返回由特定作者过滤的 UserAuthor 管理器,以某种方式获取它,但如何?!

我的试验是:

class AuthorListView(ListView):
    model = Author

    def get_queryset(self):
        final_list = []
        authors_list = list(Author.objects.all())
        for author in authors_list:
            element = author.userauthors.filter(user=self.request.user)
            final_list.append(element)
        return final_list

我肯定不喜欢这个解决方案,但是如何以更好的方式做到这一点?

【问题讨论】:

  • 我还没有测试过自己,所以我犹豫是否支持链接的答案,但这个问题的 annotate 答案对我来说似乎是合理的:stackoverflow.com/questions/40599681/… - 注释 when userauthors=self.request.user
  • @PeterDeGlopper 从该答案到该问题的解决方案的方式并非易事。如果userauthors__user=req.useruserauthors__is_follow=True,您会想要注释一个布尔字段,但这些条件必须由相同的UserAuthor 实例满足...
  • 我认为你应该能够用两个子句 When - Author.models.annotate(followed=Case(When(userauthors__user=self.request.user, userauthors__is_follow=True), ...)) 封装它 - 但同样,未经测试

标签: python django


【解决方案1】:

正如 PeterDeGlopper 在 cmets 中指出的,您可以使用注解:

from django.db.models import Case, When, Value, BooleanField
followed_ids = UserAuthor.objects.\
    filter(user=self.request.user, is_follow=True).\
    values_list('author_id', flat=True)
final_list = Author.objects.annotate(followed=Case(
    When(id__in=followed_ids, then=Value(True)),
    default=Value(False),
    output_field=BooleanField()
))

现在您可以访问此查询集的每个实例的属性followed

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 2020-04-07
    相关资源
    最近更新 更多