Django REST Framework下JSON转Protocol Buffer时Parse缺参数报错如何解决
问题排查结果
错误原因
你调用的google.protobuf.json_format.Parse方法要求传入两个必填参数:
- 待解析的JSON格式字符串
- 要填充数据的预定义Protobuf消息类的空实例
你只传入了第一个JSON参数,缺少第二个必填的消息实例参数,所以抛出参数缺失错误。
前置依赖
首先你需要先完成Protobuf消息定义和代码生成:
- 编写对应字段的
.proto消息定义文件,示例如下:
syntax = "proto3"; message User { string name = 1; string age = 2; string city = 3; string phone_number = 4; }
- 使用protoc编译器生成Python版本的消息类,执行命令:
protoc --python_out=. user.proto
执行完成后会生成user_pb2.py文件,里面包含了生成的User消息类。
修正后的代码
import json from rest_framework.views import APIView from rest_framework.response import Response from google.protobuf.json_format import Parse # 导入你生成的Protobuf消息类 from .user_pb2 import User class Proto(APIView): def get(self, request, *args, **kwargs): try: data = { "name": "Ashutosh", "age": "26", "city": "gurgaon", "phone_number": "9717" } # 移除冗余的str转ast再dumps操作,直接序列化字典为JSON json_data = json.dumps(data) # 初始化空的Protobuf消息实例,作为第二个参数传入Parse方法 user_message = User() Parse(json_data, user_message) # 可选:如果需要获取protobuf二进制数据,调用SerializeToString方法 # pb_binary = user_message.SerializeToString() return Response({'status':'SUCCESS','data':"pending...."},status=200) except Exception as e: return Response({'status':'ERROR','message':str(e)})
可选优化
如果你不想额外做JSON序列化,可以直接使用ParseDict方法直接传入Python字典,代码更简洁:
from google.protobuf.json_format import ParseDict # ...其余代码不变 user_message = User() ParseDict(data, user_message)
注意事项
- Protobuf消息定义的字段名、数据类型必须和传入的字典/JSON字段完全匹配,否则会抛出解析异常
- 如果字段是数值类型,不要传入字符串格式的值,需要和proto定义的类型保持一致
内容的提问来源于stack exchange,提问作者Ashutosh mishra
相关产品推荐
相关产品推荐

