gpt4 book ai didi

带有 GenericViewSet 的 Django 休息框架 : Filter results base on query parameters from the url

转载 作者:行者123 更新时间:2023-12-03 08:59:29 25 4
gpt4 key购买 nike

我的应用程序正在使用 GenericViewSet 和 ListModelMixin。我使用 filter_backendsfilter_class 来过滤结果。 (请参阅下面的屏幕截图中的'list':serializers.BookingListSerializer)

enter image description here

我正在编写以下简介:

假设我有一个预先过滤的动物列表(使用 filter_backends),然后在 UI 上向用户显示。

  1. 用户可以根据 UI 中的某些搜索条件(例如名称、类型、颜色)进一步过滤结果。这些过滤由 filter_class 处理。

  2. 在用户界面上的单独选项卡中,仅显示类型的动物,而不是整个动物集合。并且可以再次根据名称和颜色进一步过滤。

我必须创建 2 个单独的端点来向用户显示两种结果(以便更好地控制结果......干吧!)。但我不知道如何在 Django 中创建它们,因为 animalsdogs 使用相同的 django 模式,并且过滤器后端和过滤器类仅应用于实际莫代尔即在动物名单上。

我需要简单的 def list1(request)def list2(request) ,我可以在其中根据请求参数和我的请求过滤 query_set过滤器后端和过滤器类。

api.py

class BookingViewSet(
MultipleSerializerMixin,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet
):
lookup_field = 'uuid'
queryset = models.Booking.objects.all()
permission_classes = [DRYPermissions, ]
filter_backends = [filters.BookingFilterBackend, DjangoFilterBackend, ]
filter_class = filters.BookingFilter
pagination_class = BookingViewSetPagination
serializer_class = serializers.BookingDetailSerializer

serializer_classes = {
'create': serializers.BookingCreateUpdateSerializer,
'update': serializers.BookingCreateUpdateSerializer,
'duplicate': serializers.BookingCreateUpdateSerializer,
'list': serializers.BookingListSerializer,
'list_drafts': serializers.BookingListSerializer,
'create_draft': serializers.BookingCreateUpdateSerializer,
'submit_draft': serializers.BookingCreateUpdateSerializer,
}

def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)

booking = services.create_booking(serializer.validated_data)
data = serializers.BookingDetailSerializer(booking, context={'request': request}).data

return response.Created(data)

def update(self, request, *args, **kwargs):
booking = self.get_object()

partial = kwargs.pop('partial', False)
serializer = self.get_serializer(booking, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)

booking = services.update_booking(booking, serializer.validated_data)

async('shootsta.bookings.tasks.booking_update_google_calendar_event', booking.pk)

data = serializers.BookingDetailSerializer(booking, context={'request': request}).data

return response.Ok(data)

@detail_route(methods=['POST'], url_path='duplicate')
def duplicate(self, request, *args, **kwargs):
booking = self.get_object()

new_booking = services.duplicate_booking(booking)

data = serializers.BookingDetailSerializer(new_booking, context={'request': request}).data

return response.Created(data)

@list_route(methods=['GET'], url_path='list-drafts')
def list_drafts(self, request, *args, **kwargs):
# Code goes here! Here i'll get some params from url like state and title and then return filtered the results.
pass

@list_route(methods=['POST'], url_path='create-draft')
def create_draft(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)

booking = services.create_booking(serializer.validated_data, constants.BookingMode.draft)
data = serializers.BookingDetailSerializer(booking, context={'request': request}).data

return response.Created(data)

@detail_route(methods=['POST'], url_path='submit-draft')
def submit_draft(self, request, *args, **kwargs):
booking = self.get_object()
booking.submit_draft(by=request.user)
booking.save()

data = serializers.BookingDetailSerializer(booking, context={'request': request}).data

return response.Ok(data)

@detail_route(methods=['POST'], url_path='approve')
def approve(self, request, *args, **kwargs):
booking = self.get_object()
booking.approve(by=request.user)
booking.save()

data = serializers.BookingDetailSerializer(booking, context={'request': request}).data

return response.Ok(data)

filters.py

# Standard Library
import operator
from functools import reduce

# Third Party
from django.db.models import Q
from django_filters import rest_framework as filters
from dry_rest_permissions.generics import DRYPermissionFiltersBase

# Project Local
from . import models


class BookingFilterBackend(DRYPermissionFiltersBase):
def filter_list_queryset(self, request, queryset, view):
if request.user.is_role_admin:
return queryset

if request.user.is_role_client:
return queryset.filter(Q(client=request.user.client))

if request.user.is_role_camop:
return queryset.filter(Q(camera_operator=request.user))

return queryset.filter(Q(created_by=request.user))


def filter_booking_title(queryset, name, value):
"""
Split the filter value into separate search terms and construct a set of queries from this. The set of queries
includes an icontains lookup for the lookup fields for each of the search terms. The set of queries is then joined
with the OR operator.
"""
lookups = ['title__icontains', ]

or_queries = []

search_terms = value.split()

for search_term in search_terms:
or_queries += [Q(**{lookup: search_term}) for lookup in lookups]

return queryset.filter(reduce(operator.or_, or_queries))


class BookingFilter(filters.FilterSet):
title = filters.CharFilter(method=filter_booking_title)

class Meta:
model = models.Booking
fields = [
'title',
'state',
'client',
]

最佳答案

class SampleViewset(.....):

@list_route(methods=['GET'])
def list_2(self, request, *args, **kwargs):
<b>myqueryset = MyModel.objects.all() # or whatever queryset you need to serialize
queryset = self.filter_queryset(myqueryset)</b>

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)


这里您应该注意的要点是,

1. 过滤过程正在self.filter_queryset()内执行方法,在应用过滤器后返回 QuerySet
2. 您可以使用 self.get_queryset() 方法代替 myqueryset = MyModel.objects.all()> 语句,这是执行此类操作的 DRF 方式

更新1
如果您想使用默认的 queryset ,您可以使用 get_queryset() 方法,

class SampleViewset(.....):

@list_route(methods=['GET'])
def list_2(self, request, *args, **kwargs):
<b>queryset = self.filter_queryset(self.get_queryset())</b>

page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

或者简单地说,

class SampleViewset(.....):

@list_route(methods=['GET'])
<b>def list_2(self, request, *args, **kwargs):
return self.list(self, request, *args, **kwargs)</b>

关于带有 GenericViewSet 的 Django 休息框架 : Filter results base on query parameters from the url,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52070679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com