I'm learning Django and used Sqlite3 for my site until today, I changed the database into Postgres.
My site kind of mimics Facebook. I have a ListView that will list all posts. In get_queryset()
, I annotate each post with some additional info, such as number of likes and dislikes, number of comments, have current logged in user followed the owner of the post. I also paginated the result so that my site only displays 5 post per page.
Here is my code:
class PostListView(FormMixin, ListView):
model = Post
paginate_by = 5
template_name = "network/newsfeed.jinja"
body_title = "All Posts"
context_object_name = "posts"
form_class = PostCreateForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.get_form()
context['body_title'] = self.body_title
return context
def get_queryset(self):
queryset = Post.objects.select_related('owner').annotate(
comment_count=Count('comments', distinct=True),
like_count=Count(
Case(
When(likes__is_like=True, then=Value(1)),
output_field=IntegerField
),
distinct=True
),
dislike_count=Count(
Case(
When(likes__is_like=False, then=Value(1)),
output_field=IntegerField
),
distinct=True
),
).order_by('-created_time') # improve: do we need query all?
if self.request.user.is_authenticated:
return queryset.annotate(
follow_already=Exists(
Follow.objects.filter(followed=OuterRef('owner'), follower=self.request.user)
),
like_already=Exists(
Like.objects.filter(owner=self.request.user, post_parent=OuterRef('pk'), is_like=True)
),
dislike_already=Exists(
Like.objects.filter(owner=self.request.user, post_parent=OuterRef('pk'), is_like=False)
)
)
return queryset.annotate(
follow_already=Value(False, output_field=BooleanField()),
like_already=Value(False, output_field=BooleanField())
)
My site was OK with Sqlite3. But I get an error when changing into Postgres, that occurs on line 17 in get_internal_type()
(see the picture), which tells:
TypeError: get_internal_type() missing 1 required positional argument: 'self'
The line raises the error Could you please explain what going on here? I cannot figure it out? I think the reason is the usage of annotation. When I remove them, it works. One more thing, what is the best practice: where to place annotation, I realize that I'm annotating the whole queryset but just use 5 objects in it. Thanks for your reading ^^