我是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()这对我来说不是&#39 ; t有意义,因为我通过URL
中的pk过滤我的课程希望我的问题有道理。如果您需要任何澄清,请发表评论。我知道答案很明显,但我对框架很新。
答案 0 :(得分:3)
您必须浏览rest_framework
的代码库。名为get_object
的函数使用两个名为lookup_field
和lookup_url_kwarg
的类变量,它们的默认值分别为pk
和None
。
摘自GenericAPIView
rest_framework/generics.py
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
提供的功能。相反,您正在使用pk
从url kwargs
中get_queryset
过滤掉您的结果,然后将该QuerySet结果发送到get_object
,这将再次为您做同样的事情。