在这种情况下如何应用分页(Django Rest框架)?

2024-09-27 21:23:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我构建了一个简单的社交媒体应用程序。用户可以在博客和旋转木马上发布两种类型的帖子。用户可以跟随其他用户,如果你跟随他们,你可以看到其他用户的帖子

因此,在实现主页API(主页由您关注的人的博客和旋转木马帖子组成)时,我会像这样过滤掉博客和旋转木马

blogposts = BlogPost.objects.filter(
            Q(author__profile__in=request.user.profile.followings.all())
            | Q(author=request.user)
        )

carouselposts = Carousel.objects.filter(
            Q(author__profile__in=request.user.profile.followings.all())
            | Q(author=request.user)
        )

它基本上过滤所有的博客和你关注的人的旋转木马,并在应用合适的序列化程序后返回

但是问题是当页面被加载时,如果用户在他的主页上有100篇帖子,那么所有的帖子都会同时被加载。相反,我只想在开始时加载10篇最近的文章,并在用户到达主页底部时继续加载接下来的10篇最近的文章

因为这里有两个表Blogpost和Carousel,所以我不知道如何分页

还有一个问题?如果我以某种方式对这些内容进行分页,一次发送10篇最近的帖子,它会在每次请求时只在内部查询10篇帖子,还是会一次查询所有100篇帖子,然后一块一块地发送

以下是主页API的完整代码


class HomepageBlogPostView(APIView):
    permission_classes = [permissions.IsAuthenticated]

    def get(self, request):

        blogposts = BlogPost.objects.filter(
            Q(author__profile__in=request.user.profile.followings.all())
            | Q(author=request.user)
        )
        posts_list_serializer = BlogPostSerializer(
            blogposts, many=True, context={"request": request}
        )

        carouselposts = Carousel.objects.filter(
            Q(author__profile__in=request.user.profile.followings.all())
            | Q(author=request.user)
        )

        carousels_list_serializer = CarouselSerializer(
            carouselposts, many=True, context={"request": request}
        )

        blogposts_list = list(posts_list_serializer.data)
        carousels_list = list(carousels_list_serializer.data)

        blogposts_list.extend(carousels_list)
        posts = blogposts_list
        posts.sort(key=lambda post: -post["published"])

        return Response(posts, status=status.HTTP_200_OK)

Tags: 用户inobjectsrequest主页filterprofile帖子
1条回答
网友
1楼 · 发布于 2024-09-27 21:23:28

DRF带有一个内置的paginator middleware。您只需将这些行添加到settings.py

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 10 # default value is 100
}

如果要使用不同的PAGE_SIZE对每个资源进行分页,Django core有一个用于所有类型模型对象的内置分页器类 它将是这样的:首先您通过(“-created_at”)订购_,然后使用Paginator类

from django.core.paginator import Paginator

class HomepageBlogPostView(APIView):
     permission_classes = [permissions.IsAuthenticated]

    def get_nth_page(self , n):
        PAGE_SIZE = 10 # or just define it inside settings.py

        blogposts = BlogPost.objects.filter(
           Q(author__profile__in=request.user.profile.followings.all())
            | Q(author=request.user)
        ).order_by('-created_at')
        paginated = Paginator(blogposts,PAGE_SIZE )
        return paginated.page(n).object_list

def get(self, request):
        # return page number or 1
        blogposts = self.get_nth_page(request.GET('page_number',1)) 
        
            posts_list_serializer = BlogPostSerializer(
            blogposts, many=True, context={"request": request}
        )

        carouselposts = Carousel.objects.filter(
            Q(author__profile__in=request.user.profile.followings.all())
            | Q(author=request.user)
        )

        carousels_list_serializer = CarouselSerializer(
            carouselposts, many=True, context={"request": request}
        )

        blogposts_list = list(posts_list_serializer.data)
        carousels_list = list(carousels_list_serializer.data)

        blogposts_list.extend(carousels_list)
        posts = blogposts_list
        posts.sort(key=lambda post: -post["published"])

        return Response(posts, status=status.HTTP_200_OK)

为了使所有资源的页面大小保持一致,使用DRF设置似乎更合理

相关问题 更多 >

    热门问题