发布时出现 KeyError DRF
KeyError DRF when posting
当我 post 并且我不写电子邮件或电话时,我得到 KeyError
。在我的代码中,需要电子邮件或电话,但不是两者都需要。
为什么会这样?
这是序列化器:
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = order
fields = '__all__'
extra_kwargs = {
'email': {'required': False}, 'phonenumber': {'required': False}}
def create(self, validated_data):
order= Order.objects.create(
email=validated_data['email'],
phonenumber=validated_data['phonenumber'],
food=validated_data['food']
)
这是型号:
class Order(models.Model):
date = models.DateTimeField(auto_now_add=True)
email = models.EmailField(max_length=200, unique=True)
phonenumber = models.IntegerField(unique=True)
food= models.ManyToManyField('Food', related_name='orders', blank=True)
def __str__(self):
return self.food
这是错误:
django-challenge-back | Traceback (most recent call last):
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
django-challenge-back | response = get_response(request)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
django-challenge-back | response = wrapped_callback(request, *callback_args, **callback_kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
django-challenge-back | return view_func(*args, **kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
django-challenge-back | return self.dispatch(request, *args, **kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
django-challenge-back | response = self.handle_exception(exc)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
django-challenge-back | self.raise_uncaught_exception(exc)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
django-challenge-back | raise exc
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
django-challenge-back | response = handler(request, *args, **kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/generics.py", line 190, in post
django-challenge-back | return self.create(request, *args, **kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 19, in create
django-challenge-back | self.perform_create(serializer)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 24, in perform_create
django-challenge-back | serializer.save()
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 205, in save
django-challenge-back | self.instance = self.create(validated_data)
django-challenge-back | File "/app/order/serializers.py", line 39, in create
django-challenge-back | email=validated_data['email'],
django-challenge-back | KeyError: 'email'
django-challenge-back | [16/Apr/2021 20:02:22] "POST /pedido HTTP/1.1" 500 103807
原问题的答案:
如果 email
不在 validated_data
中,email=validated_data['email']
将抛出 KeyError
,phonenumber
也是如此。
您可以事先检查密钥是否存在或使用 .get
语法来避免错误,如果不存在则获取 None
值。
如果电子邮件不存在,email=validated_data.get('email')
将 return None
,而不是 KeyError
.
为新方法编辑:
如果不需要,您需要允许空值(请参阅电子邮件和电话号码中添加的 null=True
):
class Order(models.Model):
date = models.DateTimeField(auto_now_add=True)
email = models.EmailField(max_length=200, unique=True, null=True)
phonenumber = models.IntegerField(unique=True, null=True)
food= models.ManyToManyField('Food', related_name='orders', blank=True)
现在不需要电子邮件或电话号码。如果你想让其中之一被要求添加一个 validate
方法到你的序列化程序来检查其中之一是否存在。
类似于:
class OrderSerializer(serializers.ModelSerializer):
def validate(self, data):
email = data.get('email')
phonenumber = data.get('phonenumber')
if not email and not phonenumber:
raise serializers.ValidationError("one of email or phone number required")
return data
当我 post 并且我不写电子邮件或电话时,我得到 KeyError
。在我的代码中,需要电子邮件或电话,但不是两者都需要。
为什么会这样?
这是序列化器:
class OrderSerializer(serializers.ModelSerializer):
class Meta:
model = order
fields = '__all__'
extra_kwargs = {
'email': {'required': False}, 'phonenumber': {'required': False}}
def create(self, validated_data):
order= Order.objects.create(
email=validated_data['email'],
phonenumber=validated_data['phonenumber'],
food=validated_data['food']
)
这是型号:
class Order(models.Model):
date = models.DateTimeField(auto_now_add=True)
email = models.EmailField(max_length=200, unique=True)
phonenumber = models.IntegerField(unique=True)
food= models.ManyToManyField('Food', related_name='orders', blank=True)
def __str__(self):
return self.food
这是错误:
django-challenge-back | Traceback (most recent call last):
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
django-challenge-back | response = get_response(request)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
django-challenge-back | response = wrapped_callback(request, *callback_args, **callback_kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
django-challenge-back | return view_func(*args, **kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
django-challenge-back | return self.dispatch(request, *args, **kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
django-challenge-back | response = self.handle_exception(exc)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
django-challenge-back | self.raise_uncaught_exception(exc)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
django-challenge-back | raise exc
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
django-challenge-back | response = handler(request, *args, **kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/generics.py", line 190, in post
django-challenge-back | return self.create(request, *args, **kwargs)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 19, in create
django-challenge-back | self.perform_create(serializer)
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/mixins.py", line 24, in perform_create
django-challenge-back | serializer.save()
django-challenge-back | File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 205, in save
django-challenge-back | self.instance = self.create(validated_data)
django-challenge-back | File "/app/order/serializers.py", line 39, in create
django-challenge-back | email=validated_data['email'],
django-challenge-back | KeyError: 'email'
django-challenge-back | [16/Apr/2021 20:02:22] "POST /pedido HTTP/1.1" 500 103807
原问题的答案:
如果email
不在 validated_data
中,email=validated_data['email']
将抛出 KeyError
,phonenumber
也是如此。
您可以事先检查密钥是否存在或使用 .get
语法来避免错误,如果不存在则获取 None
值。
email=validated_data.get('email')
将 return None
,而不是 KeyError
.
为新方法编辑:
如果不需要,您需要允许空值(请参阅电子邮件和电话号码中添加的 null=True
):
class Order(models.Model):
date = models.DateTimeField(auto_now_add=True)
email = models.EmailField(max_length=200, unique=True, null=True)
phonenumber = models.IntegerField(unique=True, null=True)
food= models.ManyToManyField('Food', related_name='orders', blank=True)
现在不需要电子邮件或电话号码。如果你想让其中之一被要求添加一个 validate
方法到你的序列化程序来检查其中之一是否存在。
类似于:
class OrderSerializer(serializers.ModelSerializer):
def validate(self, data):
email = data.get('email')
phonenumber = data.get('phonenumber')
if not email and not phonenumber:
raise serializers.ValidationError("one of email or phone number required")
return data