json - 如何编写 DRF 序列化程序来处理封装模型中定义的数据字段的 JSON 包装器?
问题描述
我正在使用 Django Rest Framework 编写一个 REST API,并且需要知道如何编写一个序列化程序来处理这个 json 请求
{
"user_form": {
"fields": [
{"email": "tom.finet@hotmail.co.uk"},
{"password": "password"},
{"profile": {
"username": "Tom Finet",
"bio": "I like running, a lot.",
"location": "Switzerland"
}}
]
}
}
User 和 Profile 对象都存在模型,因此我使用 ModelSerializer 来简化序列化。但是,相关的用户和配置文件数据被包装在一个user_form
和fields
信封中。因此,当我发出 POST 请求来创建用户时,服务器会返回400
带有BadRequest
.
这是用户和配置文件序列化程序
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = '__all__'
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ('email', 'password', 'profile')
def create(self, validated_data):
email_data = validated_data.pop('email')
password_data = validated_data.pop('password')
created, user = User.objects.get_or_create_user(
email=email_data,
password=password_data
)
return user
这是 api 创建视图:
def create(self, request):
user_serializer = UserSerializer(data=request.data)
if user_serializer.is_valid(raise_exception=True):
user_serializer.save()
return Response(
user_serializer.data,
status=status.HTTP_201_CREATED
)
我想要发生的是序列化程序从指定的 json 请求创建用户,但我不知道如何处理包装用户和配置文件数据的信封。
解决方案
根据我的评论,
考虑修改您的帖子有效负载(客户端),如下所示:
{
"email": "tom.finet@hotmail.co.uk",
"password": "password",
"profile": {
"username": "Tom Finet",
"bio": "I like running, a lot.",
"location": "Switzerland"
}
}
在此之后,您当前的序列化程序类就足够了。
如果无法在客户端上更改您的 post 有效负载,请考虑使用以下推导推断它以在您的视图中手动实例化您的序列化程序:
serializer = UserSerializer(data={
k: v
for d in request.data.get('user_form').get('fields')
for k, v in d.items()
})
if not serializer.is_valid():
# handle invalid serializer error
pass
# save the new model
serializer.save()
推荐阅读
- javascript - 如何在同一函数中更改 useState 变量
- python - 2 相同的函数给出不同的结果?Python
- c# - 错误 CS1022:类型或命名空间定义,或统一预期的文件结尾
- r - 遍历多个数据帧
- ruby-on-rails - Rails 6 - Heroku 上的 InvalidAuthenticityToken
- android-studio - org.gradle.tooling.model.UnsupportedMethodException:不支持的方法:AndroidArtifact.getBuildConfigFields()
- swift - 错误:将实体添加到 CoreData 时“在实体中找不到键路径索引”
- javascript - Node JS ProductProvider.getItem 在 JSON 中找不到项目
- python - 在 Python (matplotlib) 中使用交互式光标十字准线显示 y 坐标值
- laravel - Laravel:尝试将 url 字符串推送到数据库中的数组