with tutorial the para latest framework español desde cero applications django api pagination django-rest-framework django-pagination

tutorial - Paginación en Django REST Framework?



the django project (4)

Respuesta copiada del enlace de Tom arriba en caso de pudrición futura de bit:

class TrackSerializer(serializers.ModelSerializer): class Meta: model = Track fields = (''order'', ''title'') class PaginatedTrackSerializer(pagination.PaginationSerializer): class Meta: object_serializer_class = TrackSerializer class AlbumSerializer(serializers.ModelSerializer): tracks = serializers.SerializerMethodField(''paginated_tracks'') class Meta: model = Album fields = (''album_name'', ''artist'', ''tracks'') def paginated_tracks(self, obj): paginator = Paginator(obj.tracks.all(), 10) tracks = paginator.page(1) serializer = PaginatedTrackSerializer(tracks) return serializer.data

Estamos utilizando Django REST Framework para nuestra API y tenemos la necesidad de paginar los campos de relación que devuelven varios elementos.

Para demostrar el uso de ejemplos similares a los de la documentación :

class TrackSerializer(serializers.ModelSerializer): class Meta: model = Track fields = (''order'', ''title'') class AlbumSerializer(serializers.ModelSerializer): tracks = TrackSerializer(many=True) class Meta: model = Album fields = (''album_name'', ''artist'', ''tracks'')

Ejemplo de salida serializada para un álbum:

{ ''album_name'': ''The Grey Album'', ''artist'': ''Danger Mouse'' ''tracks'': [ {''order'': 1, ''title'': ''Public Service Annoucement''}, {''order'': 2, ''title'': ''What More Can I Say''}, {''order'': 3, ''title'': ''Encore''}, ... ], }

Esto se vuelve problemático cuando hay, por ejemplo, cientos de pistas en el álbum. ¿Hay alguna manera de paginar las ''pistas'' en este caso?

Idealmente, sé que en casos como este, las ''pistas'' deberían apuntar a una URL API que simplemente devuelve las pistas para un álbum en particular, que a su vez se puede paginar fácilmente. La desventaja de ese enfoque es la solicitud adicional (y por lo tanto demora, etc.) requerida para obtener incluso las primeras pistas. En nuestro caso, es importante que podamos obtener al menos algunas de las Pistas con la solicitud única a la API de Álbum y luego cargar dinámicamente el resto de las pistas cuando sea necesario.

¿Ofrece el DRF alguna característica o patrón específico para esto? ¿O hay algún problema?


Desde DRF 3.1, PaginationSerializer no es compatible. Aquí hay una solución.

settings.py

REST_FRAMEWORK = { ''DEFAULT_PAGINATION_CLASS'': ''rest_framework.pagination.PageNumberPagination'', ''PAGE_SIZE'': 5 }

serializers.py

from myapp.models import Album, Track from rest_framework import pagination, serializers class AlbumSerializer(serializers.HyperlinkedModelSerializer): tracks = serializers.SerializerMethodField(''paginated_tracks'') class Meta: model = Album def paginated_tracks(self, obj): tracks = Track.objects.filter(album=obj) paginator = pagination.PageNumberPagination() page = paginator.paginate_queryset(tracks, self.context[''request'']) serializer = TrackSerializer(page, many=True, context={''request'': self.context[''request'']}) return serializer.data class TrackSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Track

O puede sustituir def paginated_tracks por

from rest_framework.settings import api_settings def get_paginated_tracks(self, obj): tracks = Track.objects.filter(album=obj)[:api_settings.PAGE_SIZE] serializer = TrackSerializer(tracks, many=True, context={''request'': self.context[''request'']}) return serializer.data

Incluso requiere una consulta menos que la anterior.


Creo una API en archivos de vista y obtengo una alerta de error " Exception Type: KeyError Exception Value:''request''" . ¿Dónde estableciste la request ? Mi código api:

class getAlbumsList(APIView): def get(self,request,token,format=None): page = request.query_params.get(''page'') tracks = Albums.objects.filter(designer=2)[:3] serializer = AlbumSerializer(categorys, many=True) return serializer.data


Los métodos de Malcolm Box y Deepak Prakash pueden ayudar a serializar los objetos relatológicos, pero tal como dijo @eugene anteriormente, solo funciona para un solo Alum. Para un Álbum podemos hacer esto:

serializers.py

class TrackSerializer(serializers.ModelSerializer): class Meta: model = Track fields = (''order'', ''title'') class AlbumSerializer(serializers.ModelSerializer): tracks = TrackSerializer(many=True) class Meta: model = Album fields = (''album_name'', ''artist'', ''tracks'') depth=1

apis.py

class getAPIView(generics.ListAPIView): serializer_class=TrackSerializer filter_backends = (filters.OrderingFilter,) def get_queryset(self): queryset=Track.objects.all() return queryset def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) serializer = self.get_serializer(page, many=True) data=serializer.data albums=Album.objects.values_list(''album_name'').all() trackObjs=[] albumObjs=[] self.categoryKeyList(albums,albumObjs) if page is not None: for p in page: for n,i in enumerate(albums): if re.search(str(p.alum),str(i)): albumObjs[n][''track''].append(p) data={} data[''count'']=self.get_paginated_response(self).data[''count''] data[''next'']=self.get_paginated_response(self).data[''next''] data[''previous'']=self.get_paginated_response(self).data[''previous''] data[''pageNumber''] = self.paginator.page.number data[''countPage''] = self.paginator.page.paginator._count serializer=ClientsCategorySerializer(categoryObjs,many=True) data[''result'']=serializer.data return Response({''data'':data,''success'':''1'',''detail'':u''获得客户列表成功''}) def categoryKeyList(self,albums,albumObjs): for i in albums: albumObjs={} albumObjs[''album_name'']=i[0] track=[] albumObj[''track'']=track albumObjs.append(albumObj)

Entonces puede obtener la respuesta:

{ data[ { ''album_name'': ''The Grey Album'', ''tracks'': [ {''order'': 1, ''title'': ''Public Service Annoucement''}, {''order'': 2, ''title'': ''What More Can I Say''}, {''order'': 3, ''title'': ''Encore''}, ... }, {''album_name'': ''The John Album'', ''tracks'': [ {''order'': 1, ''title'': ''Public Annoucement''}, {''order'': 2, ''title'': ''What sd Can I Say''}, {''order'': 3, ''title'': ''sd''}, ... }, ...... }