使用 ModelViewSet 的 django-filter 和 django 自定义分页
django-filter and django custom pagination with ModelViewSet
我实现了一个结合了 django-filter 和 django 默认分页的模型视图集。当我使用 django-filter 或 django 分页时,它工作正常。但是当它们同时使用时,我会得到重复的响应结果。
那么在带有 CBV 的 django-filter 中使用分页的正确方法是什么?
class TableMetaView(ModelViewSet):
"""
This will be used to create new tables.
You require to add the table fields in json request and also the job request associated with that
table.
If you want to create new table then pass CREATE NEW TABLE
In response you will get the table list along with the job request for each tables
"""
serializer_class = TableMetaSerializer
queryset = TableMeta.objects.all()
renderer_classes = [JSONRenderer]
filterset_fields = [
"schema_name",
"type",
"status",
"grouping__name",
"dataset__name",
]
ordering_fields = ["created_on", "modified_on"]
ordering = ["-modified_on"]
pagination_class = StandardResultsSetPagination
permission_classes = [
UserHasDatasetChangeAccess & IsTableEditable,
]
def get_queryset(self):
if getattr(self, "swagger_fake_view", False):
# queryset just for schema generation metadata
return TableMeta.objects.none()
return TableMeta.objects.filter(
dataset=get_object_or_404(DataSet, id=self.request.META.get(DATASET_ID, ""))
)
经过大量搜索后,我设法做了一些更改,现在代码 运行 可以正常使用 django-filters 和分页。
custom_pagination.py
from collections import OrderedDict
from constance import config
from rest_framework.pagination import ( # noqa
CursorPagination,
LimitOffsetPagination,
PageNumberPagination,
)
from rest_framework.response import Response
class MyPagination(PageNumberPagination):
page_size = 5
page_size_query_param = "page_size"
max_page_size = 50
def get_paginated_response(self, data):
return Response(
OrderedDict(
{
"next": self.get_next_link(),
"previous": self.get_previous_link(),
"results": data,
}
)
)
views.py
class TableMetaView(ModelViewSet):
"""
This will be used to create new tables.
You require to add the table fields in json request and also the job request associated with that
table.
If you want to create new table then pass CREATE NEW TABLE
In response you will get the table list along with the job request for each tables
"""
serializer_class = TableMetaSerializer
queryset = TableMeta.objects.all()
renderer_classes = [JSONRenderer]
filterset_class = TableFilter
ordering_fields = ["created_on", "modified_on"]
ordering = ["-modified_on"]
pagination_class = MyPagination
permission_classes = [
UserHasDatasetChangeAccess & IsTableEditable,
]
def get_queryset(self):
if getattr(self, "swagger_fake_view", False):
# queryset just for schema generation metadata
return TableMeta.objects.none()
return TableMeta.objects.filter(
dataset=get_object_or_404(DataSet, id=self.request.META.get(DATASET_ID, ""))
)
def list(self, request: Request, *args: Any, **kwargs: Any) -> Response:
filtered_qs = self.filterset_class(request.GET, queryset=self.get_queryset()).qs
page = self.paginate_queryset(queryset=filtered_qs)
serializer = self.serializer_class(page, many=True)
return self.get_paginated_response(serializer.data)
custom_filter.py
class TableFilter(django_filters.FilterSet):
class Meta:
model = TableMeta
fields = {
"name": ["exact", "icontains"],
"schema_name": ["exact"],
"type": ["exact"],
"status": ["exact"],
"grouping__name": ["exact"],
"dataset__name": ["exact"],
}
还需要设置默认顺序
models.py
class TableMeta(models.Model):
class Meta:
ordering = ['-modified_on'] # list of fields here
此后 django-filters 和分页在 ModelViewSet 中工作正常。
我实现了一个结合了 django-filter 和 django 默认分页的模型视图集。当我使用 django-filter 或 django 分页时,它工作正常。但是当它们同时使用时,我会得到重复的响应结果。
那么在带有 CBV 的 django-filter 中使用分页的正确方法是什么?
class TableMetaView(ModelViewSet):
"""
This will be used to create new tables.
You require to add the table fields in json request and also the job request associated with that
table.
If you want to create new table then pass CREATE NEW TABLE
In response you will get the table list along with the job request for each tables
"""
serializer_class = TableMetaSerializer
queryset = TableMeta.objects.all()
renderer_classes = [JSONRenderer]
filterset_fields = [
"schema_name",
"type",
"status",
"grouping__name",
"dataset__name",
]
ordering_fields = ["created_on", "modified_on"]
ordering = ["-modified_on"]
pagination_class = StandardResultsSetPagination
permission_classes = [
UserHasDatasetChangeAccess & IsTableEditable,
]
def get_queryset(self):
if getattr(self, "swagger_fake_view", False):
# queryset just for schema generation metadata
return TableMeta.objects.none()
return TableMeta.objects.filter(
dataset=get_object_or_404(DataSet, id=self.request.META.get(DATASET_ID, ""))
)
经过大量搜索后,我设法做了一些更改,现在代码 运行 可以正常使用 django-filters 和分页。
custom_pagination.py
from collections import OrderedDict
from constance import config
from rest_framework.pagination import ( # noqa
CursorPagination,
LimitOffsetPagination,
PageNumberPagination,
)
from rest_framework.response import Response
class MyPagination(PageNumberPagination):
page_size = 5
page_size_query_param = "page_size"
max_page_size = 50
def get_paginated_response(self, data):
return Response(
OrderedDict(
{
"next": self.get_next_link(),
"previous": self.get_previous_link(),
"results": data,
}
)
)
views.py
class TableMetaView(ModelViewSet):
"""
This will be used to create new tables.
You require to add the table fields in json request and also the job request associated with that
table.
If you want to create new table then pass CREATE NEW TABLE
In response you will get the table list along with the job request for each tables
"""
serializer_class = TableMetaSerializer
queryset = TableMeta.objects.all()
renderer_classes = [JSONRenderer]
filterset_class = TableFilter
ordering_fields = ["created_on", "modified_on"]
ordering = ["-modified_on"]
pagination_class = MyPagination
permission_classes = [
UserHasDatasetChangeAccess & IsTableEditable,
]
def get_queryset(self):
if getattr(self, "swagger_fake_view", False):
# queryset just for schema generation metadata
return TableMeta.objects.none()
return TableMeta.objects.filter(
dataset=get_object_or_404(DataSet, id=self.request.META.get(DATASET_ID, ""))
)
def list(self, request: Request, *args: Any, **kwargs: Any) -> Response:
filtered_qs = self.filterset_class(request.GET, queryset=self.get_queryset()).qs
page = self.paginate_queryset(queryset=filtered_qs)
serializer = self.serializer_class(page, many=True)
return self.get_paginated_response(serializer.data)
custom_filter.py
class TableFilter(django_filters.FilterSet):
class Meta:
model = TableMeta
fields = {
"name": ["exact", "icontains"],
"schema_name": ["exact"],
"type": ["exact"],
"status": ["exact"],
"grouping__name": ["exact"],
"dataset__name": ["exact"],
}
还需要设置默认顺序
models.py
class TableMeta(models.Model):
class Meta:
ordering = ['-modified_on'] # list of fields here
此后 django-filters 和分页在 ModelViewSet 中工作正常。