Django加入多个外部字段(左连接)

时间:2016-10-12 04:54:01

标签: django django-models

我正在使用django 1.10并拥有以下两个模型

class Post(models.Model):
    title = models.CharField(max_length=500)
    text = models.TextField()

class UserPost(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    approved = models.BooleanField(default=False)

如何获取所有帖子的列表,包括登录用户的“已批准”属性(如果存在)?因此,它不是多个查询,而是一个左连接查询,伪代码:

select * from posts as p 
left join user_posts as up
on up.post_id = p.post_id
and up.user_id = 2

输出

post_id | title | text  | user_id | approved
1       | 'abc' | 'abc' | 2       | true
2       | 'xyz' | 'xyz' | null    | null
3       | 'foo' | 'bar' | 2       | true

我以这种方式创建了模型,因为'approved'属性属于用户。每个用户都可以批准/拒绝帖子。其他用户可以批准和拒绝同一帖子。模型应该设置不同吗?

由于

更新 我正在尝试创建一个网页来显示所有可用的帖子,并突出显示当前用户批准的帖子。我可以列出所有帖子,然后为每个帖子检查'UserPost'表是否有值,如果是,则获得批准的属性,否则忽略。但这意味着,如果我有100个帖子,我正在对数据库进行100 + 1次调用。是否可以使用ORM进行1次呼叫?如果无法做到这一点,模型应该设置不同吗?

1 个答案:

答案 0 :(得分:1)

然后我认为你需要这样的东西:

Post.objects.all().annotate(
    approved=models.Case(
        models.When(userpost_set__user_id=2, 
                    then=models.F('userpost__approved')),
        default=models.Value(False),
        output_field=models.BooleanField()
    )
)