Post 通过序列化器请求一个对象 many=False
Post request with an object via serializer many=False
我正在尝试使用一个对象发出 POST
请求,例如这就是我发送请求的方式:
{
"title": "Haloween",
"body": " This is one of the greatest ones",
"grade_level": {
"id": 2,
"country": "UG"
},
"tags": [{"name": "Jamming"}]
}
所以我想 post 一个对象 :
"grade_level": {
"id": 2,
"country": "UG"
}
下面是我使用的序列化程序:
class GradeClassSerializer(CountryFieldMixin, serializers.ModelSerializer):
"""GradeClass Serializer."""
class Meta:
model = ClassGrade
fields = ('id', 'grade', 'country', 'color_code', )
class PostSerializer(serializers.ModelSerializer):
"""Post Serializer"""
owner = UserProfile(read_only=True)
tags = TagSerializer(many=True)
comments = CommentSerializer(many=True, read_only=True)
slug = serializers.SlugField(read_only=True)
grade_level = GradeClassSerializer(many=False)
当我发送对象 grade_level
时,我似乎无法接收到它,它只接收到 ID :
def create(self, validated_data):
"""Create a blog post in a customized way."""
grade_level = validated_data.pop('grade_level', {})
status = validated_data.pop('status', '')
post = Post.objects.create(**validated_data,
owner=self.context['request'].user)
if grade_level:
grade = ClassGrade.objects.get(id=grade_level['id'])
post.grade_level = grade
post.save()
return post
当我发出请求时,会发生以下情况:
KeyError: 'id'
对象只有 country
没有 id
。
这是 grade_level = validated_data.pop('grade_level', {})
打印的内容:
OrderedDict([('country', 'UG')])
如何从对象中获取id
。
注意:
- id 未标记为 read_only
编辑:
在下面的 views.py
中是视图 :
class PostList(generics.ListCreateAPIView):
"""Blog post lists"""
queryset = Post.objects.filter(status=APPROVED)
serializer_class = serializers.PostSerializer
authentication_classes = (JWTAuthentication,)
permission_classes = (PostsProtectOrReadOnly, IsMentorOnly)
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data, context={
'request': request})
if serializer.is_valid():
serializer.save()
return response.Response(serializer.data,
status=status.HTTP_201_CREATED, )
return response.Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
然后模型:
class ClassGrade(TimeStampedModel, models.Model):
"""ClassGrade is the class which Identifies the class or grade."""
grade = models.CharField(
_('Name'), max_length=150, null=True, blank=True)
country = CountryField()
color_code = ColorField(format='hexa', default='#33AFFF', null=True)
def __str__(self):
return self.grade
class Post(MainProcess, TimeStampedModel, models.Model):
"""Post model."""
title = models.CharField(_('Title'), max_length=100, blank=False,
null=False)
image = models.ImageField(_('Image'), upload_to='blog_images', null=True,
max_length=900)
body = models.TextField(_('Body'), blank=False)
description = models.CharField(_('Description'), max_length=400,
blank=True, null=True)
因此,默认情况下,如果您未定义字段,DRF 将使用 ModelSerializer 中的模型字段。因为 Id 是一个自动创建的主键(如果你没有明确覆盖它,Django 会这样做)并且 Django 假定主键是只读的,反序列化请求中省略了 id
默认情况下,DRF 将 ModelSerializer 中的 id(PrimaryKey) 视为只读。因此,要覆盖此行为,您可以尝试 PrimaryKeyRelatedField
class GradeClassSerializer(CountryFieldMixin, serializers.ModelSerializer):
"""GradeClass Serializer."""
id = serializers.PrimaryKeyRelatedField(queryset=ClassGrade.objects.all(),
required=True)
class Meta:
model = ClassGrade
fields = ('id', 'grade', 'country', 'color_code', )
我正在尝试使用一个对象发出 POST
请求,例如这就是我发送请求的方式:
{
"title": "Haloween",
"body": " This is one of the greatest ones",
"grade_level": {
"id": 2,
"country": "UG"
},
"tags": [{"name": "Jamming"}]
}
所以我想 post 一个对象 :
"grade_level": {
"id": 2,
"country": "UG"
}
下面是我使用的序列化程序:
class GradeClassSerializer(CountryFieldMixin, serializers.ModelSerializer):
"""GradeClass Serializer."""
class Meta:
model = ClassGrade
fields = ('id', 'grade', 'country', 'color_code', )
class PostSerializer(serializers.ModelSerializer):
"""Post Serializer"""
owner = UserProfile(read_only=True)
tags = TagSerializer(many=True)
comments = CommentSerializer(many=True, read_only=True)
slug = serializers.SlugField(read_only=True)
grade_level = GradeClassSerializer(many=False)
当我发送对象 grade_level
时,我似乎无法接收到它,它只接收到 ID :
def create(self, validated_data):
"""Create a blog post in a customized way."""
grade_level = validated_data.pop('grade_level', {})
status = validated_data.pop('status', '')
post = Post.objects.create(**validated_data,
owner=self.context['request'].user)
if grade_level:
grade = ClassGrade.objects.get(id=grade_level['id'])
post.grade_level = grade
post.save()
return post
当我发出请求时,会发生以下情况:
KeyError: 'id'
对象只有 country
没有 id
。
这是 grade_level = validated_data.pop('grade_level', {})
打印的内容:
OrderedDict([('country', 'UG')])
如何从对象中获取id
。
注意:
- id 未标记为 read_only
编辑:
在下面的 views.py
中是视图 :
class PostList(generics.ListCreateAPIView):
"""Blog post lists"""
queryset = Post.objects.filter(status=APPROVED)
serializer_class = serializers.PostSerializer
authentication_classes = (JWTAuthentication,)
permission_classes = (PostsProtectOrReadOnly, IsMentorOnly)
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
def post(self, request, *args, **kwargs):
serializer = self.serializer_class(data=request.data, context={
'request': request})
if serializer.is_valid():
serializer.save()
return response.Response(serializer.data,
status=status.HTTP_201_CREATED, )
return response.Response(serializer.errors,
status=status.HTTP_400_BAD_REQUEST)
然后模型:
class ClassGrade(TimeStampedModel, models.Model):
"""ClassGrade is the class which Identifies the class or grade."""
grade = models.CharField(
_('Name'), max_length=150, null=True, blank=True)
country = CountryField()
color_code = ColorField(format='hexa', default='#33AFFF', null=True)
def __str__(self):
return self.grade
class Post(MainProcess, TimeStampedModel, models.Model):
"""Post model."""
title = models.CharField(_('Title'), max_length=100, blank=False,
null=False)
image = models.ImageField(_('Image'), upload_to='blog_images', null=True,
max_length=900)
body = models.TextField(_('Body'), blank=False)
description = models.CharField(_('Description'), max_length=400,
blank=True, null=True)
因此,默认情况下,如果您未定义字段,DRF 将使用 ModelSerializer 中的模型字段。因为 Id 是一个自动创建的主键(如果你没有明确覆盖它,Django 会这样做)并且 Django 假定主键是只读的,反序列化请求中省略了 id
默认情况下,DRF 将 ModelSerializer 中的 id(PrimaryKey) 视为只读。因此,要覆盖此行为,您可以尝试 PrimaryKeyRelatedField
class GradeClassSerializer(CountryFieldMixin, serializers.ModelSerializer):
"""GradeClass Serializer."""
id = serializers.PrimaryKeyRelatedField(queryset=ClassGrade.objects.all(),
required=True)
class Meta:
model = ClassGrade
fields = ('id', 'grade', 'country', 'color_code', )