Django-Filter 并使用数组进行查询
Django-Filter and query with an array
我有一个简单的问题:目前我可以这样做以从我的后端获取一个对象:
http://127.0.0.1:8000/api/v1/boats/boats?id=10
http://127.0.0.1:8000/api/v1/boats/boats?home_port=98&id=5
但我想根据 ID 列表或 home_ports 列表获取一组船,我已经尝试过:
http://127.0.0.1:8000/api/v1/boats/boats?id=10,11
http://127.0.0.1:8000/api/v1/boats/boats?id_in=10,11
http://127.0.0.1:8000/api/v1/boats/boats?id=10,id=11
http://127.0.0.1:8000/api/v1/boats/boats?id=10&id=11
但是这些都不行。使用 django-filter 执行此操作的最佳方法是什么,URL 规则是如何定义的?
这是我的观点:
class BoatList(generics.ListCreateAPIView):
permission_classes = (IsOwnerOrReadOnly,)
serializer_class = BoatSerializer
queryset = Boat.objects.all()
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('id', 'home_port',)
我标记为 100% 接受的解决方案回答了我的问题,但我最终实现了基于另一个 post 我发现使用过滤器的不同的东西:
class ListFilter(Filter):
def filter(self, qs, value):
if not value:
return qs
self.lookup_type = 'in'
values = value.split(',')
return super(ListFilter, self).filter(qs, values)
class BoatFilter(FilterSet):
ids = ListFilter(name='id')
class Meta:
model = Boat
fields = ['home_port', 'ids']
class BoatList(generics.ListCreateAPIView):
permission_classes = (IsOwnerOrReadOnly,)
serializer_class = BoatSerializer
queryset = Boat.objects.all()
filter_backends = (filters.DjangoFilterBackend,)
filter_class = BoatFilter
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
试试这个:
url: http://127.0.0.1:8000/api/v1/boats/boats?id=10,11
class BoatList(generics.ListCreateAPIView):
permission_classes = (IsOwnerOrReadOnly,)
serializer_class = BoatSerializer
queryset = Boat.objects.filter(id__in=request.GET.getlist('id')) #<------
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('id', 'home_port',)
doniyor的回答很贴切。但我猜 request
在使用它的地方将不可用。
还有另一种方法 this.You 可以覆盖 get_queryset
方法。这可以按如下方式完成:
class BoatList(generics.ListCreateAPIView):
permission_classes = (IsOwnerOrReadOnly,)
serializer_class = BoatSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('id', 'home_port',)
def get_queryset(self):
id_list = self.request.GET.getlist("id")
if not id_list:
return []
return Boat.objects.filter(id__in=id_list)
您刚刚创建了一个过滤器class
class NumberInFilter(BaseInFilter, NumberFilter):
pass
class myFilter(FilterSet):
id__in = NumberInFilter(field_name='id', lookup_expr='in')
class Meta:
model = Boat
在视图集中使用
filter_class = myFilter
你可以看到django-filter的这篇文档:
https://django-filter.readthedocs.io/en/master/ref/filters.html?highlight=BaseInFilter
我有一个简单的问题:目前我可以这样做以从我的后端获取一个对象:
http://127.0.0.1:8000/api/v1/boats/boats?id=10
http://127.0.0.1:8000/api/v1/boats/boats?home_port=98&id=5
但我想根据 ID 列表或 home_ports 列表获取一组船,我已经尝试过:
http://127.0.0.1:8000/api/v1/boats/boats?id=10,11
http://127.0.0.1:8000/api/v1/boats/boats?id_in=10,11
http://127.0.0.1:8000/api/v1/boats/boats?id=10,id=11
http://127.0.0.1:8000/api/v1/boats/boats?id=10&id=11
但是这些都不行。使用 django-filter 执行此操作的最佳方法是什么,URL 规则是如何定义的?
这是我的观点:
class BoatList(generics.ListCreateAPIView):
permission_classes = (IsOwnerOrReadOnly,)
serializer_class = BoatSerializer
queryset = Boat.objects.all()
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('id', 'home_port',)
我标记为 100% 接受的解决方案回答了我的问题,但我最终实现了基于另一个 post 我发现使用过滤器的不同的东西:
class ListFilter(Filter):
def filter(self, qs, value):
if not value:
return qs
self.lookup_type = 'in'
values = value.split(',')
return super(ListFilter, self).filter(qs, values)
class BoatFilter(FilterSet):
ids = ListFilter(name='id')
class Meta:
model = Boat
fields = ['home_port', 'ids']
class BoatList(generics.ListCreateAPIView):
permission_classes = (IsOwnerOrReadOnly,)
serializer_class = BoatSerializer
queryset = Boat.objects.all()
filter_backends = (filters.DjangoFilterBackend,)
filter_class = BoatFilter
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
试试这个:
url: http://127.0.0.1:8000/api/v1/boats/boats?id=10,11
class BoatList(generics.ListCreateAPIView):
permission_classes = (IsOwnerOrReadOnly,)
serializer_class = BoatSerializer
queryset = Boat.objects.filter(id__in=request.GET.getlist('id')) #<------
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('id', 'home_port',)
doniyor的回答很贴切。但我猜 request
在使用它的地方将不可用。
还有另一种方法 this.You 可以覆盖 get_queryset
方法。这可以按如下方式完成:
class BoatList(generics.ListCreateAPIView):
permission_classes = (IsOwnerOrReadOnly,)
serializer_class = BoatSerializer
filter_backends = (filters.DjangoFilterBackend,)
filter_fields = ('id', 'home_port',)
def get_queryset(self):
id_list = self.request.GET.getlist("id")
if not id_list:
return []
return Boat.objects.filter(id__in=id_list)
您刚刚创建了一个过滤器class
class NumberInFilter(BaseInFilter, NumberFilter):
pass
class myFilter(FilterSet):
id__in = NumberInFilter(field_name='id', lookup_expr='in')
class Meta:
model = Boat
在视图集中使用
filter_class = myFilter
你可以看到django-filter的这篇文档: https://django-filter.readthedocs.io/en/master/ref/filters.html?highlight=BaseInFilter