【问题标题】:Django Rest-Framework price range additional filter?Django Rest-Framework 价格范围附加过滤器?
【发布时间】:2019-08-03 20:13:09
【问题描述】:

我的 Django Rest-Framework API 中有以下 Django 视图

from django_filters.rest_framework import DjangoFilterBackend, RangeFilter, FilterSet
from rest_framework.filters import OrderingFilter, SearchFilter

from rest_framework import generics
from api.serializers import UserSerializer
from django.contrib.auth.models import User
from rest_framework import permissions
from api.permissions import IsOwnerOrReadOnly

from MyGameDBWebsite.models import Game, GameDeveloper, GameGenre, GameConsole
from api.serializers import GameSerializer, DeveloperSerializer, GenreSerializer, ConsoleSerializer


class GameList(generics.ListCreateAPIView):
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    serializer_class = GameSerializer

    filter_backends = (DjangoFilterBackend, OrderingFilter, SearchFilter,)
    filter_fields = ('owner__username', 'id', 'game_title', 'game_developer_name', 'game_console',
                     'game_genre', 'game_release_year', 'game_price',)

    ordering_fields = ('owner__username', 'id', 'game_title', 'game_developer_name', 'game_console',
                       'game_genre', 'game_release_year', 'game_price',)

    search_fields = ('game_title', 'game_release_year', 'game_price',)

    queryset = Game.objects.all()

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

我的输出网址如下: http://127.0.0.1:8000/api/?owner__username=&id=&game_title=&game_developer_name=&game_console=&game_genre=&game_release_year=&game_price=

我想创建一个价格范围,以便我可以从 URL 调用 API 以获取价格范围内的结果

【问题讨论】:

    标签: django django-rest-framework


    【解决方案1】:

    您应该定义一个filterset_class 并在您的视图中使用它。

    对于RangeFilter,您应该使用RangeFilter定义您的价格字段

    示例

    class GameFilter(filters.FilterSet):
        game_price = filters.RangeFilter()
    
        class Meta:
            model = Game
            fields = ['game_price']

    因此您的网址将是/api/?game_price_min=123&game_price_max=321

    【讨论】:

    • 不能有范围加上上面的url组合吗?
    • 范围是有两个值的,对吧?而且您的网址上只有一个参数,即game_price。无论如何,您打算如何使用单个 url 参数传递范围值(两个值)?
    • 除此之外,DRF 或 django-filter 不会从给定的 url 检测范围过滤器,除非您以正确的语法/设置给出它
    • 像这样:127.0.0.1:8000/api/… Develpoper1 给出的所有价格范围内的游戏的例子
    • 我不明白
    【解决方案2】:

    指定过滤器集 对于更高级的过滤要求,您可以指定应由视图使用的 FilterSet 类。例如:

    import django_filters
    from myapp.models import Game
    from myapp.serializers import GameSerializer
    from rest_framework import generics
    
    
    class GameListFilter(django_filters.FilterSet):
    min_price = django_filters.NumberFilter(name="price", lookup_type='gte')
    max_price = django_filters.NumberFilter(name="price", lookup_type='lte')
    class Meta:
        model = Game
        fields = ['min_price', 'max_price']
    
    
    class GameList(generics.ListAPIView):
    queryset = Game.objects.all()
    serializer_class = GameSerializer
    filter_class = GameListFilter
    

    这将允许您提出以下请求:

    http://example.com/api/games?max_price=8.00
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-09
      • 2020-12-26
      • 2017-10-26
      • 2016-04-11
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 2016-09-26
      相关资源
      最近更新 更多