Python Django REST框架中ViewSet的设置页面

Python Django REST框架中ViewSet的设置页面,python,django,django-views,django-rest-framework,Python,Django,Django Views,Django Rest Framework,我有以下代码: class GeonamesCountryViewSet(viewsets.ReadOnlyModelViewSet): permission_classes = (AllowAny,) serializer_class = GeonamesCountrySerializer ordering = ('country_name',) offset_limit = 'required' def get_queryset(self):

我有以下代码:

class GeonamesCountryViewSet(viewsets.ReadOnlyModelViewSet):
    permission_classes = (AllowAny,)
    serializer_class = GeonamesCountrySerializer
    ordering = ('country_name',)
    offset_limit = 'required'

    def get_queryset(self):
        country_geoname_ids = self.request.QUERY_PARAMS.get('country_geoname_ids', None)
        name_prefix = self.request.QUERY_PARAMS.get('name_prefix', None)

        if (country_geoname_ids is None) and (name_prefix is None):
            raise exceptions.ParseError("Either 'country_geoname_id' or 'name_prefix' must be defined.")

        if country_geoname_ids is not None:
            country_geoname_ids = [param.strip() for param in country_geoname_id.split(',')]
            queryset = GeonamesCountry.objects.filter(country_geoname_id__in = country_geoname_ids)

        if name_prefix is not None:
            if len(name_prefix) < 2:
                raise exceptions.ParseError("'name_prefix' must be at least 2 characters long")
            queryset = GeonamesCountry.objects.filter(country_name__istartswith = name_prefix)

        paginator = Paginator(queryset, self.request.QUERY_PARAMS.get('limit', 10))
        selected_page = self.request.QUERY_PARAMS.get('page')

        try:
            countries = paginator.page(selected_page)
        except EmptyPage:
            raise exceptions.ParseError("'Page Empty")


        return queryset
class GeonamesCountryViewSet(ViewSet.ReadOnlyModelViewSet):
权限\类=(允许,)
serializer\u class=GeonamesCountrySerializer
排序=(‘国家名称’,)
偏移量\限制='必需'
def get_queryset(自我):
country\u geoname\u ids=self.request.QUERY\u PARAMS.get('country\u geoname\u ids',None)
name\u prefix=self.request.QUERY\u PARAMS.get('name\u prefix',None)
如果(国家/地区\地理名称\ ID为无)和(名称\前缀为无):
引发异常。ParseError(“必须定义'country\u geoname\u id'或'name\u prefix'”)
如果国家/地区\u地理名称\u ID不是无:
country_geoname_id=[param.strip()表示country_geoname_id.split(',')中的参数]
queryset=GeonamesCountry.objects.filter(country\u geoname\u id\u in=country\u geoname\u id)
如果name_前缀不是None:
如果len(名称前缀)<2:
引发异常。ParseError(“'name\u prefix'长度必须至少为2个字符”)
queryset=GeonamesCountry.objects.filter(country\u name\u istartswith=name\u前缀)
paginator=paginator(queryset,self.request.QUERY_PARAMS.get('limit',10))
所选页面=self.request.QUERY\u PARAMS.get('页面')
尝试:
国家/地区=paginator.page(所选页面)
除空页外:
引发异常。ParseError(“页面为空”)
返回查询集
当抛出EmptyPage异常时,是否可以默认为第1页而不是
引发异常。ParseError('page Empty')


阅读文档后,我发现不使用视图集很容易做到,但如何在视图集中做到这一点?

我认为这样做会非常安全:

try:
    countries = paginator.page(selected_page)
except InvalidPage:
    countries = paginator.page(1)
请注意
InvalidPage
例外,因此您也可以覆盖非数字

--更新--

似乎最干净的方法是重写分页类,这是唯一可以让您控制返回页码的方法:

from django.core.paginator import Paginator, InvalidPage

class MyPaginator(Paginator):
    def validate_number(self, number):
        try:
            number = super(MyPaginator, self).validate_number(number)
        except InvalidPage:
            number = 1

        return number


class GeonamesCountryViewSet(viewsets.ReadOnlyModelViewSet):
    paginator_class = MyPaginator
    ...

我认为你这样做会很安全:

try:
    countries = paginator.page(selected_page)
except InvalidPage:
    countries = paginator.page(1)
请注意
InvalidPage
例外,因此您也可以覆盖非数字

--更新--

似乎最干净的方法是重写分页类,这是唯一可以让您控制返回页码的方法:

from django.core.paginator import Paginator, InvalidPage

class MyPaginator(Paginator):
    def validate_number(self, number):
        try:
            number = super(MyPaginator, self).validate_number(number)
        except InvalidPage:
            number = 1

        return number


class GeonamesCountryViewSet(viewsets.ReadOnlyModelViewSet):
    paginator_class = MyPaginator
    ...

谢谢你的回答。是的,实际上我知道这一点,但是我的问题是如何在ViewSet的输出上设置分页器?视图集本身负责页面分页,因此即使我使用您在上面输入的代码,它也不会将页面设置为第1页。谢谢您的回答。是的,实际上我知道这一点,但是我的问题是如何在ViewSet的输出上设置分页器?视图集本身负责页面分页,因此即使我使用上面的代码,它也不会将页面设置为第1页。