Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
DjangoRestFramework-序列化程序验证会引发KeyError,即使它是由perform_create()方法提供的_Django_Django Rest Framework - Fatal编程技术网

DjangoRestFramework-序列化程序验证会引发KeyError,即使它是由perform_create()方法提供的

DjangoRestFramework-序列化程序验证会引发KeyError,即使它是由perform_create()方法提供的,django,django-rest-framework,Django,Django Rest Framework,这是我的视图集: class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer permission_classes = (IsAuthenticated, IsLikeOrOwnerDeleteOrReadOnly,) def perform_create(self, serializer): #

这是我的视图集:

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.')
问题是,即使我从我的
perform\u create()
方法将
locaiton
传递给序列化程序,我在尝试创建帖子时也会遇到一个错误。错误是:

if data['location'] == data['page']:
    KeyError: 'location'
我假设DRF在执行
perform\u create()
方法之前进行序列化程序验证检查?如果是,我如何完成我需要的?(即,当从我的视图将
位置
传递给序列化程序并且
页面
来自我的序列化程序时,我如何检查
数据['location']==data['page']
)。

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

您可以通过在调用时包含其他关键字参数来完成此操作 .save()

serializer.save(owner=request.user)

任何其他关键字参数都将包含在 调用.create()或.update()时验证了\u数据参数

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

那么,如何将额外的数据传递给序列化程序呢?使用上下文序列化程序

在视图中重写
get\u serializer\u 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.')

啊好的。根据您的回答,我意识到我也可以在验证函数中执行此操作:
location=self.context.get('request',None.).user.userextended.location
。这与您提到的方法(即从视图的
get\u serializer\u context()
方法返回
location
)有什么不同(在性能和最佳实践方面)?@user2719875取决于,在我看来,您的可读性更强,只需要使用
self.context.get('location')
来获取用户位置,想象一下你需要做一个更复杂的操作,以你的方式,你需要一次又一次地重复那个“计算”。重写get_serializer_上下文的目的是完全归档您正试图执行的操作。也要确保模型的外键(如“User”)具有属性
null=True
,这样您就可以在
perform\u create
上插入它。否则,即使在调用
perform\u create
之前,也会引发错误。