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

注意:

编辑: 在下面的 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', )