首页 文章

Django Rest Framework . 检索如何工作

提问于
浏览
0

我是Django休息框架的新手,我有几个问题可以为我清理很多东西 .

我正在查看有关简单CRUD通用视图的文档,例如ListAPIView,Retrieve ...等 .

对于我的列表视图,我创建了它:

class CourseListApiView(ListAPIView):
    queryset = Course.objects.all()
    serializer_class = CourseListSerializer

这是有道理的,因为queryset返回Course.objects.all()所以所有课程都会出现 .

我不清楚的是RetrieveApi中的查询集是如何工作的

class CourseRetrieveAPIView(RetrieveAPIView):
    queryset = Course.objects.all()
    serializer_class = CourseRetrieveSerializer

这是我的检索视图,它从我的链接中获取pk并返回相应的课程 . 我不清楚的是,为什么查询集是Course.objects.all(),而不是从URL获取kwargs并过滤我的课程的过滤查询 . 我按照自己的方式尝试并获得相同的结果,我的观点是:

class CourseRetrieveAPIView(RetrieveAPIView):
    serializer_class = CourseRetrieveSerializer

    def get_queryset(self):
        queryset = Course.objects.filter(pk=self.kwargs.get('pk'))
        return queryset

这更有意义,因为查询集是Course.objects.filter(pk = self.kwargs.get('pk'))而不是Course.objects.all()这对我来说没有意义,因为我正在过滤我的课程通过URL中的pk

希望我的问题有道理 . 如果您需要任何澄清,请发表评论 . 我知道答案很明显,但我对框架很新

1 回答

  • 2

    您将不得不通过 rest_framework 的代码库 . 名为 get_object 的函数使用两个名为 lookup_fieldlookup_url_kwarg 的类变量,它们的默认值分别为 pkNone .

    rest_framework/generics.pyGenericAPIView 的摘录

    def get_object(self):
        """
        Returns the object the view is displaying.
    
        You may want to override this if you need to provide non-standard
        queryset lookups.  Eg if objects are referenced using multiple
        keyword arguments in the url conf.
        """
        queryset = self.filter_queryset(self.get_queryset())
    
        # Perform the lookup filtering.
        lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
    
        assert lookup_url_kwarg in self.kwargs, (
            'Expected view %s to be called with a URL keyword argument '
            'named "%s". Fix your URL conf, or set the `.lookup_field` '
            'attribute on the view correctly.' %
            (self.__class__.__name__, lookup_url_kwarg)
        )
    
        filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
        obj = get_object_or_404(queryset, **filter_kwargs)
    
        # May raise a permission denied
        self.check_object_permissions(self.request, obj)
    
        return obj
    

    如您所见,如果未指定任何内容, lookup_url_kwarg 将设置为等于 lookup_field . 如果将此值更改为需求字段,则 get_object_or_404 中的过滤器会更改 .

    现在回到您的问题,当您使用 url kwargs 手动指定过滤器时,您没有使用 RetrieveAPIView 提供的功能 . 相反,你正在做的是在 get_queryset 中从 url kwargs 过滤掉你的结果,然后将那个QuerySet结果发送到 get_object ,这将再次为你做同样的事情 .

相关问题