Reputation: 2080
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)
and from those model classes, I want to get posts that is not followed by some user.
Like this:
user = User.objects.get(pk=1)
not_followed_post = Post.objects.filter(Q(pk__lte=1000) & ~Q(self__is_not_followed_by_user=user))
How can I do this?
Upvotes: 1
Views: 40
Reputation: 477309
I think it more self-explaining when using .exclude(..)
:
not_followed_post = Post.objects.exclude(
postfollow__user=user
).filter(
pk__lte=1000
)
The .exclude(..)
will perform universal quantification in a transparent way.
I tink it is probably better to add explicit related_name
s here, to make it easier to pinpoint where the relation is looking at. For example:
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'
)
The pk__lte
is rather weird. Usually the pk
is used only as an identifier. Making queries like __lte
is of course possible, but rather uncommon.
Yes, pk
s are typically "distributed" in creation order (given you do not specify an explicit one), so if you never assign expliclty, you could probably use it to obtain more recent records than a given record. But still I think it is a bit "risky" to start filtering in such way. If you for example later add historical data to the database, then these can (depending on how you insert the data) have higher id
s, and thus show up in the results.
Upvotes: 3