尝试访问ViewSet中的request.data时出现KeyError'id'创建定义 [英] KeyError 'id' when trying to access request.data in ViewSet create definition

查看:56
本文介绍了尝试访问ViewSet中的request.data时出现KeyError'id'创建定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近从drf 2.4升级到了v3,并一直试图覆盖其中一个ViewSet中的 def Create 。但是,当尝试访问已保存到序列化器变量的request.data时,会收到错误消息: KeyError在/ api / appointments /
'id'

I recently upgraded from drf 2.4 to v3 and have been trying to override the def Create in one of my ViewSets. However when trying to access the request.data that i've saved to a serializer variable i'll receive an error: KeyError at /api/appointments/ 'id'

我包括我的ViewSet代码,序列化程序和以下错误的回溯:

I'm including my ViewSet code, serializer, and the traceback from the error below:

class AppointmentViewSet(viewsets.ModelViewSet):
    queryset = Appointment.objects.all()
    serializer_class = AppointmentSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                      IsOwnerOrReadOnly,)
    def create(self, request):
            serializer = AppointmentSerializer(data=request.data)
            if serializer.is_valid(raise_exception=True):
            #get the datetime object from the request data and filter availability objects, datetime stored in attribute .when
                    avQueryset = Availability.objects.filter(date__range=(serializer.data.when, serializer.data.when))
    def pre_save(self, obj):
            obj.service_recipient = self.request.user

序列化器

class AppointmentSerializer(serializers.ModelSerializer):
        class Meta:
                model = Appointment
                fields = ('id','availability' , 'business_location', 'services', 'when', 'service_recipient', 'completed')

repr(序列化器)

AppointmentSerializer():
    id = IntegerField(label='ID', read_only=True)
    availability = PrimaryKeyRelatedField(queryset=Availability.objects.all())
    business_location = PrimaryKeyRelatedField(queryset=BusinessLocation.objects.all())
    services = PrimaryKeyRelatedField(many=True, queryset=Service.objects.all())
    when = DateTimeField(allow_null=True, required=False)
    service_recipient = PrimaryKeyRelatedField(queryset=User.objects.all())
    completed = BooleanField(help_text='Set to true when appointment has been completed.', required=False)

跟踪

Environment:


Request Method: POST
Request URL: http://104.131.110.138/api/appointments/

Django Version: 1.7.1
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'webapp',
 'rest_framework')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/csrf.py" in wrapped_view
  57.         return view_func(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/viewsets.py" in view
  85.             return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/views.py" in dispatch
  407.             response = self.handle_exception(exc)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/views.py" in dispatch
  404.             response = handler(request, *args, **kwargs)
File "/home/appointments/appointments/webapp/views.py" in create
  57.                   avQueryset = Availability.objects.filter(date__range=(serializer.data.when, serializer.data.when))
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in data
  422.         ret = super(Serializer, self).data
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in data
  179.                 self._data = self.to_representation(self.validated_data)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/serializers.py" in to_representation
  387.             attribute = field.get_attribute(instance)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/fields.py" in get_attribute
  277.         return get_attribute(instance, self.source_attrs)
File "/usr/local/lib/python2.7/dist-packages/rest_framework/fields.py" in get_attribute
  65.                 instance = instance[attr]

Exception Type: KeyError at /api/appointments/
Exception Value: 'id'


推荐答案

当您似乎要使用 serializer时,您正在使用 serializer.data 。 validated_data 。当您要序列化现有对象时,实际上应该只使用 serializer.data ,这需要传递 instance

You are using serializer.data when you appear to mean to be using serializer.validated_data. You should really only use serializer.data when you are looking to serialize an existing object, which would require passing an instance into the serialier when you are initializing it.

问题是您没有将实例传递给序列化程序。 ,因此期望传递给它的 initial 数据可以序列化。这将需要 data 具有序列化程序上的所有字段,包括 id 似乎不存在的所有字段。 。

The issue is that you are not passing an instance into the serializer, so it is expecting that the initial data passed into it can be serialized. This would require the data to have all of the fields on the serializer, including id which doesn't appear to exist.

您可以使用 serializer.validated_data [ when] 来获取经过验证的数据,而不是序列化的数据。 。 Django REST Framework文档在反序列化对象下特别提到了这一点

You can get the validated data, not the serialized data, using serializer.validated_data["when"]. This is specifically mentioned in the documentation for Django REST Framework under deserializing objects.

这篇关于尝试访问ViewSet中的request.data时出现KeyError'id'创建定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆