DjangoRestFramework - 即使由perform_create()方法提供,也会引发KeyError验证KeyError

时间:2015-11-09 03:33:42

标签: django django-rest-framework

这是我的ViewSet:

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = (IsAuthenticated, IsLikeOrOwnerDeleteOrReadOnly,)

    def perform_create(self, serializer):
        # Passing location to the serializer.
        serializer.save(owner=self.request.user, location=self.request.user.userextended.location)

这是我的序列化器:

class PostSerializer(serializers.ModelSerializer):

    class Meta:
        model = Post
        fields = ('id', 'owner', 'post', 'page', 'location')
        read_only_fields = ('id', 'owner', 'location')

    def create(self, validated_data):
        post = Post(
                owner =  validated_data['owner'],
                post = validated_data['post'],
                location = validated_data['location'],
        )

        if validated_data.get('page', None):
            post.page = validated_data['page']

        post.save()

        return post

    def validate(self, data):
        if not data.get('page', None):
            return data
        # The KeyError being raised points to the line below.
        if data['location'] == data['page']:
            return data
        raise serializers.ValidationError('Error.')

问题是,即使我从locaiton方法将perform_create()传递给序列化程序,但在尝试创建帖子时出现错误。错误是:

if data['location'] == data['page']:
    KeyError: 'location'

我假设DRF在执行perform_create()方法之前执行了序列化程序验证检查?如果是的话,我该如何完成我需要的工作? (例如,当data['location'] == data['page']从我的视图传递到序列化程序并且location来自我的序列化程序时,如何检查page是否为int wCounts[A_ROWS] = {0}; int yCounts[A_ROWS] = {0}; int zCounts[A_ROWS] = {0};

1 个答案:

答案 0 :(得分:1)

根据DRF文档。

  

有时您会希望您的视图代码能够注入额外的内容   保存实例时的数据。这些额外的数据可能   包括当前用户,当前时间或等信息   其他任何不属于请求数据的内容。

     

您可以在调用时添加其他关键字参数   .save()

     

serializer.save(owner=request.user)

     

任何其他关键字参数都将包含在   调用.create()或.update()时的validated_data参数。

因此,您只能在create()update()方法中访问额外的关键字参数,而不能在validate()

中访问

说,如何将额外数据传递给序列化程序?使用上下文序列化器

在视图中覆盖get_serializer_context方法

class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    permission_classes = (IsAuthenticated, IsLikeOrOwnerDeleteOrReadOnly,)

    get_serializer_context(self):
         return {'location':self.request.user.userextended.location}

然后在验证序列化方法

def validate(self, data):
    if not data.get('page', None):
        return data
    location = self.context.get('location')
    if location == data['page']:
        return data
    raise serializers.ValidationError('Error.')