在这种情况下如何制作Q对象表达式(按ForeignKey字段过滤)?

时间:2018-10-02 12:35:02

标签: django django-orm

models.py:

class Post(models.Model):
    title = models.TextField(max_length=1000, null=True, blank=True, default=None)
    created = models.DateTimeField(auto_now_add=True)


class PostFollow(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)

从这些模型类中,我希望获得一些用户不关注的帖子。

赞:

user = User.objects.get(pk=1)

not_followed_post = Post.objects.filter(Q(pk__lte=1000) & ~Q(self__is_not_followed_by_user=user))

我该怎么做?

1 个答案:

答案 0 :(得分:3)

我认为使用.exclude(..)时更容易理解:

not_followed_post = Post.objects.exclude(
    postfollow__user=user
).filter(
    pk__lte=1000
)

.exclude(..)将以透明的方式执行通用量化

我想想可能最好在这里添加显式related_name,以使查明关系的位置变得容易。例如:

class PostFollow(models.Model):
    post = models.ForeignKey(
        Post,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='postfollow'
    )
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        null=True,
        blank=True,
        related_name='postfollow'
    )

pk__lte很奇怪。通常pk仅用作标识符。当然可以进行类似__lte的查询,但这并不常见。

是的,pk通常按创建顺序“分配”(假设您未指定显式记录),因此,如果您从未分配显式记录,则可以使用它来获取比给定记录更多的最近记录。记录。但是我仍然认为以这种方式开始过滤有点“麻烦”。例如,如果您以后将 historical 数据添加到数据库中,则这些数据(取决于插入数据的方式)可以具有更高的id,从而显示在结果中。