【问题标题】:How to add get_queryset function in apiview of Django rest framework?如何在Django rest框架的apiview中添加get_queryset函数?
【发布时间】:2021-10-30 14:44:00
【问题描述】:

我正在使用 Django APIView 将我的所有 CRUD 操作包含在单个 api 端点中。但后来我不得不根据已传递的查询参数使用过滤逻辑。因此,我发现很难将其包含在 APIView 的 get api 中,并使用通用视图 ListAPiview 制作了一个单独的 api。

这里是视图:

class LeadsView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request, pk=None, *args, **kwargs):

        id = pk
        if id is not None:
            abc = Lead.objects.get(id=id)
            serializer = LeadSerializer(abc)
            return serializer.data

    def post(self,request,*args,**kwargs):
        abc = LeadSerializer(data=request.data,many=True)
        if abc.is_valid():
            abc.save()
            return Response(abc.data, status=status.HTTP_201_CREATED)
        return Response(abc._errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request,pk, *args, **kwargs):

现在,我必须使用过滤器类和一些自定义过滤逻辑,我需要使用 get_queryset。因此,我必须为我不想要的 get 方法创建另一个 api。

class LeadAPIView(ListAPIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    queryset = Lead.objects.all().order_by('-date_created')
    serializer_class = LeadSerializer
    filter_backends = [django_filters.rest_framework.DjangoFilterBackend]
    pagination_class = CustomPagination
    # filterset_fields = [ 'email','first_name','last_name','phone']
    filterset_class = LeadsFilter

    def get_queryset(self):
        source = self.request.GET.get("source", None)    #     
        lead_status = self.request.GET.get("lead_status", None)
        if source is not None:
            source_values = source.split(",")
            if lead_status is not None:
                lead_status_values= lead_status.split(",")
                return Lead.objects.filter(source__in=source_values,lead_status__in=lead_status_values)
            else:
                return Lead.objects.filter(source__in=source_values)
        elif lead_status is not None:
            lead_status_values = lead_status.split(",")
            if source is not None:
                source_values = source.split(",")
                return Lead.objects.filter(lead_status__in=lead_status_values,source__in=source_values)
            else:
                return Lead.objects.filter(lead_status__in=lead_status_values)

        return Lead.objects.all()

我的问题是,我可以在 APIView 中使用 get_queryset 而不是制作另一个 api 吗?另外,如果我可以使用它,我假设我不能导入filterset_class = LeadsFilter 和分页?最好的方法是什么??

我的网址:

path('leads', LeadAPIView.as_view(), name='leads'),
path('lead', LeadsView.as_view(), name='leads-create'),
path('lead/<int:pk>', LeadsView.as_view()),

【问题讨论】:

    标签: django api django-rest-framework django-class-based-views django-generic-views


    【解决方案1】:

    APIView 代表 MVT 框架。有两种情况。

    1. 如果您想返回对 django 模板的响应,请使用视图。
    2. 在返回 json、xml(简短响应)对象的情况下,您使用视图集术语。 Viewsets 支持过滤器类、分页类、序列化、查询集(自定义 mixins 等等)。

    附言如果您想覆盖默认查询集,请在视图集中定义 get_queryset 方法。视图不支持这一点。另外请检查 django 中的 @action 装饰器。

    【讨论】:

    • 我不使用视图集。我只使用基类 APIVIEW 和基于通用类的视图,如 Listview、Createapiview 等
    猜你喜欢
    • 2016-06-20
    • 2021-01-16
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    相关资源
    最近更新 更多