2016-11-14 11 views
1

Django Rest Frameworkは、デフォルトではlimitoffsetの値がデフォルトの制限値とオフセット値を返しても、それらを無効にします。
min_offsetおよびmin_limitもありません。したがって、リミットとオフセットで負の値を使用できます。
私のAPIのケースでエラーを投げる必要があります。
paginate_querysetメソッドをオーバーライドしてカスタムページネーションクラスを作成し、そこで有効性を確認しました。最小制限値と最小オフセット値を検証するAPIはありますか?私は自分でそれを検証する以下のコードを持っています。Django rest frameworkはページ番号とオフセットを有効にします

paginatorのバリデーションは、ドキュメントからは言及されていないため、メソッド内に記述するか、ビューセットメソッド自体の内部で検証する必要はありますか?

class CustomPagination(pagination.LimitOffsetPagination): 
    default_limit = 25 
    max_limit = 50 
    min_limit = 1 
    min_offset = 1 
    max_offset = 50 

    def paginate_queryset(self, queryset, request, view=None): 
     limit = request.query_params.get('limit') 
     offset = request.query_params.get('offset') 

     if limit: 
      limit = int(limit) 
      if limit > self.max_limit: 
       raise serializers.ValidationError({"limit" : ["Limit should be less than or equal to {0}".format(self.max_limit)]}) 
      elif limit < self.min_limit: 
       raise serializers.ValidationError({"limit" : ["Limit should be greater than or equal to {0}".format(self.min_limit)]}) 
     if offset: 
      offset = int(offset) 
      if offset > self.max_offset: 
       raise serializers.ValidationError({"offset" : ["Offset should be less than or equal to {0}".format(self.max_offset)]}) 
      elif offset < self.min_offset: 
       raise serializers.ValidationError({"offset" : ["Offset should be greater than or equal to {0}".format(self.min_offset)]}) 

     return super(self.__class__, self).paginate_queryset(queryset, request, view) 
+0

私の答えがあなたに役立つかどうか疑問に思っていました –

+0

@John Moutafisはい。私は彼らにDRF IRCチャンネルで尋ねました。彼らは意思決定が意図的であり、それを検証するのは開発者の責任であると言いました。 – xtreak

+0

@xtreakをよく聞く:D!答えを受け入れるケア? –

答えて

1

あなたはLimitOffsetPaginationにDRFコードを見てみた場合、あなたはそれがlimitoffsetを解析するために2つのメソッドを利用していることがわかります。

  • get_limit()

    def get_limit(self, request): 
        if self.limit_query_param: 
         try: 
          return _positive_int(
           request.query_params[self.limit_query_param], 
           strict=True, 
           cutoff=self.max_limit 
          ) 
         except (KeyError, ValueError): 
          pass 
    
        return self.default_limit 
    
  • get_offset()

    def get_offset(self, request): 
        try: 
         return _positive_int(
          request.query_params[self.offset_query_param], 
         ) 
        except (KeyError, ValueError): 
         return 0 
    

ご覧のとおり、考えられる例外は、この2つの方法の中で処理されます。

したがって、これらの方法を簡単に無効にすることができ、ホイールを改造する必要もありません。
方法は再びraiseそれを例外をキャッチしてください:

class CustomPagination(pagination.LimitOffsetPagination): 
    default_limit = 25 
    max_limit = 50 
    min_limit = 1 
    min_offset = 1 
    max_offset = 50 

    def get_limit(self, request): 
     if self.limit_query_param: 
      try: 
       return _positive_int(
        request.query_params[self.limit_query_param], 
        strict=True, 
        cutoff=self.max_limit 
       ) 
      except (KeyError, ValueError) as e: 
       raise e # Re-raise the caught exception 

     return self.default_limit 

    def get_offset(self, request): 
     try: 
      return _positive_int(
       request.query_params[self.offset_query_param], 
      ) 
     except (KeyError, ValueError) as e: 
      raise e # Re-raise the caught exception 

注:
前述の作品が、あなたのアプリケーションは、ユーザーが誤ってを通るたびにクラッシュするために、それは非常に不便になりますそれを使用することを検討する必要があります。

関連する問題