[Django] 25 - DRF: Pagination and Filtering

实现图片等其他资源的逐步加载。

 

Django Rest Framework for beginners

17 videos
Last updated on Jul 20, 2021
 

Pagination

Ref: API Pagination. Django Rest Framework complete tutorial.#13

 

 

queryset.filter

  • Old

    def get_queryset(self):
        """Retrieve albums for authenticated user."""
return self.queryset.filter(user=self.request.user).order_by('-id')
  • New
    def _params_to_ints(self, qs):
        """Convert a list of strings to integers."""
        return [int(str_id) for str_id in qs.split(',')]
    def get_queryset(self):
        """Retrieve recipes for authenticated user."""
# ----------------------------------------------------------------- tags = self.request.query_params.get('tags') ingredients = self.request.query_params.get('ingredients')
queryset
= self.queryset
if tags: tag_ids = self._params_to_ints(tags) queryset = queryset.filter(tags__id__in=tag_ids) # <----
if ingredients: ingredient_ids = self._params_to_ints(ingredients) queryset = queryset.filter(ingredients__id__in=ingredient_ids) # <---- # ----------------------------------------------------------------- return queryset.filter( user=self.request.user ).order_by('-id').distinct()

 

 

Implement tag and ingredient filtering

  • app/dataset/tests/test_photos_api.py 
+    def test_filter_photos_assigned_to_albums(self):
+        """Test listing photos to those assigned to albums."""
+ + in1 = Photo.objects.create(user=self.user, name='Apples') + in2 = Photo.objects.create(user=self.user, name='Turkey') + album = Album.objects.create( + title='Apple Crumble', + time_minutes=5, + price=Decimal('4.50'), + user=self.user, + ) + album.photos.add(in1) + + res = self.client.get(PHOTOS_URL, {'assigned_only': 1}) + + s1 = PhotoSerializer(in1) + s2 = PhotoSerializer(in2) + self.assertIn(s1.data, res.data) + self.assertNotIn(s2.data, res.data) + + def test_filtered_photos_unique(self): + """Test filtered photos returns a unique list."""
+ + ing = Photo.objects.create(user=self.user, name='Eggs') + xxx = Photo.objects.create(user=self.user, name='Lentils') + album1 = Album.objects.create( + title='Eggs Benedict', + time_minutes=60, + price=Decimal('7.00'), + user=self.user, + ) + album2 = Album.objects.create( + title='Herb Eggs', + time_minutes=20, + price=Decimal('4.00'), + user=self.user, + ) + album1.photos.add(ing) + album2.photos.add(ing) + + res = self.client.get(PHOTOS_URL, {'assigned_only': 1}) + + self.assertEqual(len(res.data), 1)

 

  • app/dataset/tests/test_tags_api.py 
+    def test_filter_tags_assigned_to_albums(self):
+        """Test listing tags to those assigned to albums."""
+ + tag1 = Tag.objects.create(user=self.user, name='Breakfast') + tag2 = Tag.objects.create(user=self.user, name='Lunch') + album = Album.objects.create( + title='Green Eggs on Toast', + time_minutes=10, + price=Decimal('2.50'), + user=self.user, + ) + album.tags.add(tag1) + + res = self.client.get(TAGS_URL, {'assigned_only': 1}) + + s1 = TagSerializer(tag1) + s2 = TagSerializer(tag2) + self.assertIn(s1.data, res.data) + self.assertNotIn(s2.data, res.data) + + def test_filtered_tags_unique(self): + """Test filtered tags returns a unique list."""
+ + tag = Tag.objects.create(user=self.user, name='Breakfast') + xxx = Tag.objects.create(user=self.user, name='Dinner') + album1 = Album.objects.create( + title='Pancakes', + time_minutes=5, + price=Decimal('5.00'), + user=self.user, + ) + album2 = Album.objects.create( + title='Porridge', + time_minutes=3, + price=Decimal('2.00'), + user=self.user, + ) + album1.tags.add(tag) + album2.tags.add(tag) + + res = self.client.get(TAGS_URL, {'assigned_only': 1}) + + self.assertEqual(len(res.data), 1)

 

  • app/dataset/views.py
@extend_schema_view(
    list=extend_schema(
        parameters=[
            OpenApiParameter(
                'assigned_only',
                OpenApiTypes.INT, enum=[0, 1],
                description='Filter by items assigned to albums.',
            ),
        ]
    )
)
class BaseAlbumAttrViewSet(mixins.DestroyModelMixin,
                           mixins.UpdateModelMixin,
                           mixins.ListModelMixin,
                           viewsets.GenericViewSet):
    """Base viewset for album attributes."""
    authentication_classes = [TokenAuthentication]
    permission_classes     = [IsAuthenticated]

    def get_queryset(self):
        """Filter queryset to authenticated user."""
assigned_only = bool( int(self.request.query_params.get('assigned_only', 0)) ) queryset = self.queryset if assigned_only: queryset = queryset.filter(album__isnull=False) return queryset.filter( user=self.request.user ).order_by('-name').distinct()
class TagViewSet(BaseAlbumAttrViewSet):
    """Manage tags in the database."""
    serializer_class = serializers.TagSerializer
    queryset = Tag.objects.all()


class PhotoViewSet(BaseAlbumAttrViewSet):
    """Manage photos in the database."""
    serializer_class = serializers.PhotoSerializer
    queryset = Photo.objects.all()

 

End.

posted @ 2022-07-09 11:49  郝壹贰叁  阅读(51)  评论(0编辑  收藏  举报