Python Django Rest框架:自定义JSON序列化程序
我正在努力弄清楚如何在DRF中编写自定义序列化程序来解析传递给端点的复杂JSON数据结构。JSON如下所示:Python Django Rest框架:自定义JSON序列化程序,python,django-rest-framework,Python,Django Rest Framework,我正在努力弄清楚如何在DRF中编写自定义序列化程序来解析传递给端点的复杂JSON数据结构。JSON如下所示: { "name": "new", "site": "US", "data": { "settings": [], "meta": { "meta1":{} } } } # POST attribute of request object 'name' = 'new' 'site' =
{
"name": "new",
"site": "US",
"data": {
"settings": [],
"meta": {
"meta1":{}
}
}
}
# POST attribute of request object
'name' = 'new'
'site' = 'US'
'data[settings][0] = ''
'data[meta][meta1][] = ''
以下是我的后端代码:
# views.py
class SaveData(views.APIView):
def post(self, request, *args, **kwargs):
name = request.POST.get('name')
site = request.POST.get('site')
data = request.POST.get('data')
但是data
总是返回None
。仔细检查请求
对象后,传入的JSON如下所示:
{
"name": "new",
"site": "US",
"data": {
"settings": [],
"meta": {
"meta1":{}
}
}
}
# POST attribute of request object
'name' = 'new'
'site' = 'US'
'data[settings][0] = ''
'data[meta][meta1][] = ''
基本上,与数据
键关联的嵌套JSON对象似乎没有正确地序列化为Pythondict
和list
对象。我一直在寻找定制DRF序列化程序的示例,但我发现的大多数示例都是用于序列化Django模型的,但我不需要这样做。传入的数据不会直接映射到我的模型;相反,我需要在保存任何数据之前进行一些处理
有人对将data
JSON正确转换为正确的Python对象的自定义序列化程序有什么建议吗?我是从这个开始的,但是当序列化程序被传递一个“data”关键字参数时,它会抛出一个异常(),在尝试访问序列化的“.data”表示之前,您必须调用“.is_valid()”。
您应该首先调用“.is\u valid()”,或者改为访问“.initial\u data”。
)。以下是我创建的自定义序列化程序的代码:
# serializers.py
class SaveDataSerializer(serializers.Serializer):
name = serializers.CharField()
site = serializers.CharField()
data = serializers.DictField()
def create(self, validated_data):
return dict(**validated_data)
谢谢。当将JS对象传递给
$.ajax
时,我能够通过将JS对象转换为JSON来解决问题,然后DRF能够正确地解析为Python对象。下面是我正在使用的jQuery的一个片段:
$.ajax({
url: '/api/endpoint',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(ajaxData),
done: function(data) {}
...
})
请注意,如果不指定任何内容,jQuery将默认为x-www-urlencoded
,作为内容类型。由于我使用JSON.stringify()
方法将ajaxData
对象显式转换为JSON字符串,因此也需要显式设置内容类型
我是从这个答案中得出这个想法的:
当然,这并没有真正回答我最初的问题,但这是另一个更简单的解决方案,它可以像我所希望的那样工作。通过这样做,我不必创建任何自定义序列化程序,但我必须修改API视图,如下所示:
class SaveData(views.APIView):
def post(self, request, *args, **kwargs):
name = request.data.get('name')
site = request.data.get('site')
data = request.data.get('data')
执行此操作后,将返回预期的对象类型
>>> type(name)
str
>>> type(site)
str
>>> type(data)
dict
我能够通过将JS对象传递给$.ajax
,将其转换为JSON来解决问题,然后DRF能够正确地解析为Python对象。下面是我正在使用的jQuery的一个片段:
$.ajax({
url: '/api/endpoint',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(ajaxData),
done: function(data) {}
...
})
请注意,如果不指定任何内容,jQuery将默认为x-www-urlencoded
,作为内容类型。由于我使用JSON.stringify()
方法将ajaxData
对象显式转换为JSON字符串,因此也需要显式设置内容类型
我是从这个答案中得出这个想法的:
当然,这并没有真正回答我最初的问题,但这是另一个更简单的解决方案,它可以像我所希望的那样工作。通过这样做,我不必创建任何自定义序列化程序,但我必须修改API视图,如下所示:
class SaveData(views.APIView):
def post(self, request, *args, **kwargs):
name = request.data.get('name')
site = request.data.get('site')
data = request.data.get('data')
执行此操作后,将返回预期的对象类型
>>> type(name)
str
>>> type(site)
str
>>> type(data)
dict