Reputation: 1480
I have 3 models:
UserAuthor models which is considered as a many-to-many relationship between the previous two models, but with additional fields (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)
My question is about how to get all the authors with a field inside each author to show that the authenticated user is following him or not.
I know that I can use the related_name attribute, which returns the UserAuthor manager filtered by specific author, in some way to get it but how?!
My trial is:
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
I don't like this solution for sure, but how to do it in a better way?
Upvotes: 0
Views: 1546
Reputation: 73450
As pointed out by PeterDeGlopper in the comments, you can use annotation:
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()
))
Now you can access the attribute followed
for each instance of this queryset.
Upvotes: 1