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)
- 在class定义中,声明了变量
serializer_class
;然而在 perform_create
方法中, serializer
是一个参数。鉴于命名的差异,这两者有什么关系?
- 方法
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 没有回答我的问题——它只是解释了关键字参数是什么。我不对他们的名字感到困惑,我对他们在这段代码中不可见但隐含的引用感到困惑。
回答你的第一点,我们必须注意两点:
首先,方法perform_create
用于与CreateModelMixin
关联的create
方法(参见https://github.com/encode/django-rest-framework/blob/71e6c30034a1dd35a39ca74f86c371713e762c79/rest_framework/mixins.py#L16). The class CreateAPIView
inherits from this mixin and also from GenericAPIView
(See https://github.com/encode/django-rest-framework/blob/b1004a47334a0dd1929e6d50b8f7ff6badc959f4/rest_framework/generics.py#L184)。可以看到,上面提到的create
方法使用了classperform_create
方法,那里需要一个序列化器。定义 perform_create
时不带该参数会在使用此方法创建对象时导致错误。
另外需要注意的是,使用的序列化器来自get_serializer
方法。检查 GenericAPIView
(https://github.com/encode/django-rest-framework/blob/b1004a47334a0dd1929e6d50b8f7ff6badc959f4/rest_framework/generics.py#L103) 的源代码,我们可以看到此方法调用 get_serializer_class
检索由 serializer_class
.
定义的序列化程序
总之,如果您不修改任何其他内容,将作为参数传递的 serializer
将是您在 serializer_class
中定义的序列化程序 class 的一个实例。
进入第二点,如果您尝试搜索 GenericAPIView
的父 class 并继续搜索这些 class 继承自的基础 class ,您最终会发现基数 class 是 django.views.generic
的 View
。您会在 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.request
、self.args
和 self.kwargs
。我希望我解释清楚了!
我正在学习 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)
- 在class定义中,声明了变量
serializer_class
;然而在perform_create
方法中,serializer
是一个参数。鉴于命名的差异,这两者有什么关系? - 方法
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 没有回答我的问题——它只是解释了关键字参数是什么。我不对他们的名字感到困惑,我对他们在这段代码中不可见但隐含的引用感到困惑。
回答你的第一点,我们必须注意两点:
首先,方法
perform_create
用于与CreateModelMixin
关联的create
方法(参见https://github.com/encode/django-rest-framework/blob/71e6c30034a1dd35a39ca74f86c371713e762c79/rest_framework/mixins.py#L16). The classCreateAPIView
inherits from this mixin and also fromGenericAPIView
(See https://github.com/encode/django-rest-framework/blob/b1004a47334a0dd1929e6d50b8f7ff6badc959f4/rest_framework/generics.py#L184)。可以看到,上面提到的create
方法使用了classperform_create
方法,那里需要一个序列化器。定义perform_create
时不带该参数会在使用此方法创建对象时导致错误。另外需要注意的是,使用的序列化器来自
定义的序列化程序get_serializer
方法。检查GenericAPIView
(https://github.com/encode/django-rest-framework/blob/b1004a47334a0dd1929e6d50b8f7ff6badc959f4/rest_framework/generics.py#L103) 的源代码,我们可以看到此方法调用get_serializer_class
检索由serializer_class
.
总之,如果您不修改任何其他内容,将作为参数传递的 serializer
将是您在 serializer_class
中定义的序列化程序 class 的一个实例。
进入第二点,如果您尝试搜索 GenericAPIView
的父 class 并继续搜索这些 class 继承自的基础 class ,您最终会发现基数 class 是 django.views.generic
的 View
。您会在 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.request
、self.args
和 self.kwargs
。我希望我解释清楚了!