Django REST Framework中的一项非常标准的任务是向序列化程序提供额外的args
/ kwargs
来设置不是通过request.data
设置的字段值,而是通过值在url参数或cookie中。例如,我需要在POST请求时将我的Comment模型的user
字段设置为request.user
。这些额外的参数称为上下文。
StackOverflow上的几个问题(1,2)建议我覆盖get_serializer_context()
的{{1}}方法。我做了,但没有帮助。我试图理解,有什么不对,并且发现我不能从源代码中理解这个上下文系统应该如何工作。 (关于此事的文件也缺失了)
有人可以解释一下,序列化程序在正常请求数据中添加了上下文吗?我找到了两个地方,它从上下文中保存了值。
__new__()
,它缓存args和kwargs,但似乎以后没有人读过它们。答案 0 :(得分:11)
每当您使用通用视图或视图集时,DRF(3.3.2)会将request
对象,view
对象和format
添加到序列化程序context
。您可以使用serializer.context
进行访问,在序列化程序中说request.user
。
调用get_serializer_class()
时会添加此项。在其中,它调用get_serializer_context()
方法,其中所有这些参数都被添加到其上下文中。
DRF源代码供参考:
class GenericAPIView(views.APIView):
"""
Base class for all other generic views.
"""
def get_serializer(self, *args, **kwargs):
"""
Return the serializer instance that should be used for validating and
deserializing input, and for serializing output.
"""
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
def get_serializer_context(self):
"""
Extra context provided to the serializer class.
"""
return {
'request': self.request,
'format': self.format_kwarg,
'view': self
}
答案 1 :(得分:0)
设置不是通过request.data设置的字段值,而是通过url参数或cookie中的值设置。例如,我需要在POST请求时将我的Comment模型的用户字段设置为等于request.user。
这就是我在ModelViewSet中处理这两种情况的方法:
def perform_create(self, serializer):
# Get article id from url e.g. http://myhost/article/1/comments/
# obviously assumes urls.py is setup right etc etc
article_pk = self.kwargs['article_pk']
article = get_object_or_404(Article.objects.all(), pk=article_pk)
# Get user from request
serializer.save(author=self.request.user, article=article)
不幸的是,嵌套对象不是DRF的标准对象,但除了这一点之外。 :)