Django Views.py: kwargs 和序列化程序 w/o 在 class 定义中的显式引用

Django Views.py: kwargs and serializer w/o explicit reference in class definition

我正在学习 Django Rest Framework 教程 (source code here),我对以下代码片段有几个问题:

class ReviewCreate(generics.CreateAPIView):
    serializer_class = ReviewSerializer
    permission_classes = [IsAuthenticated]
    throttle_classes = [ReviewCreateThrottle]

    def get_queryset(self):
        return Review.objects.all()

    def perform_create(self, serializer):
        pk = self.kwargs.get('pk')
        watchlist = WatchList.objects.get(pk=pk)

        review_user = self.request.user
        review_queryset = Review.objects.filter(watchlist=watchlist, review_user=review_user)

        if review_queryset.exists():
            raise ValidationError("You have already reviewed this movie!")

        if watchlist.number_rating == 0:
            watchlist.avg_rating = serializer.validated_data['rating']
        else:
            watchlist.avg_rating = (watchlist.avg_rating + serializer.validated_data['rating'])/2

        watchlist.number_rating = watchlist.number_rating + 1
        watchlist.save()

        serializer.save(watchlist=watchlist, review_user=review_user)
  1. 在class定义中,声明了变量serializer_class;然而在 perform_create 方法中, serializer 是一个参数。鉴于命名的差异,这两者有什么关系?
  2. 方法perform_create中引用了self.kwargs。但是,我没有看到 kwargs 参数传递给任何 __init__ 方法或附加到 class object。 How/where kwargs 是否传递给了 class?

在这两种情况下,我只能假设继承的 class (generics.CreateAPIView) 有一个 __init__ 方法将 serializer_class 变量分配给 serializer.它如何“监听”child class 对 serializer_class 的定义,我不知道。至于 kwargs,我不知道它是如何传递给 child class w/o 在其参数中显式调用定义它的。

编辑,这个问题 Kwargs in Django 没有回答我的问题——它只是解释了关键字参数是什么。我不对他们的名字感到困惑,我对他们在这段代码中不可见但隐含的引用感到困惑。

回答你的第一点,我们必须注意两点:

总之,如果您不修改任何其他内容,将作为参数传递的 serializer 将是您在 serializer_class 中定义的序列化程序 class 的一个实例。

进入第二点,如果您尝试搜索 GenericAPIView 的父 class 并继续搜索这些 class 继承自的基础 class ,您最终会发现基数 class 是 django.views.genericView。您会在 setup 方法 (https://github.com/django/django/blob/27aa7035f57f0db30b6632e4274e18b430906799/django/views/generic/base.py#L124) 中找到初始化 kwargs 属性的位置。您还可以在该方法的代码文档中看到以下语句:

"""Initialize attributes shared by all view methods."""

因此,在我们创建的任何视图中(如果它以 View 作为基础 class),我们将始终能够操作 self.requestself.argsself.kwargs。我希望我解释清楚了!