同时从前端解析我的请求数据并使用序列化器转换为JSON格式。我收到一些意外错误。
当使用如下所述的使用序列化器的请求解析模式时,它显示了以下错误:(我发现以下错误使用:contact_serializer.errors]
{'phone_number': {u'non_field_errors': [u'Invalid data. Expected a dictionary, but got str.']}, 'cont_email': {u'non_field_errors': [u'Invalid data. Expected a dictionary, but got str.']}}
我有一个模特:
class RestaurantContactAssociation(models.Model):
restaurant=models.ForeignKey(Restaurant)
contact=models.ForeignKey(Contact,null=True,blank=True,related_name="restaurantcontact_association",on_delete=models.SET_NULL)
class PhoneNumber(models.Model):
contact = models.ForeignKey(Contact,related_name='contact_number')
number = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
class ContactEmail(models.Model):
contact = models.ForeignKey(Contact,related_name='contact_email')
email = models.EmailField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
我创建的序列化器是:
class PhoneNumberSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = PhoneNumber
fields = ('number')
class ContactEmailSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = ContactEmail
fields = ('email')
class CrmContactSerializer(serializers.ModelSerializer):
phone_number = PhoneNumberSerializer(source = 'contact_number')
cont_email = ContactEmailSerializer(source = 'contact_email')
class Meta:
model = RestaurantContactAssociation
fields = ('id','phone_number','cont_email','contact')
调用此序列化程序的代码部分:
request.data['phone_number'] = '9999999999'
request.data['cont_email'] = '[email protected]'
contact_name = request.data.get('c_name',None)
contact_serializer = CrmContactSerializer(data=request.data)
if contact_serializer.is_valid():
contact_serializer.save()
有人可以提出建议,我在哪里错了吗?
更新1:我在contact_serializer.save()
时收到此错误更新2:
弹出键错误。
我认为它不会像这样工作。您必须记住,如果您输入这样的值,它将最终存储在DB中,并且它是硬编码的值。即使您坚持要这样做,也要使用字典列表:
request.data['phone_number'] = [{'number': '9999999999'}]
request.data['cont_email'] = [{'email':'[email protected]'}]
并像这样更新序列化器:
class CrmContactSerializer(serializers.ModelSerializer):
phone_number = PhoneNumberSerializer(source = 'contact_number', many=True)
cont_email = ContactEmailSerializer(source = 'contact_email', many=True)
class Meta:
model = RestaurantContactAssociation
fields = ('id','phone_number','cont_email','contact')
def create(self, validated_data):
phone_number = validated_data.pop('phone_number')
cont_email = validated_data.pop('cont_email')
restaurant = super().create(validated_data)
phone_instance = PhoneNumber(**phone_number)
phone_instance.restaurant = restaurant
phone_instance.save()
email_instance = ContactEmail(**phone_number)
email_instance.restaurant = restaurant
email_instance.save()
return restaurant
many=True
的原因是,一个餐厅可以有多个号码或电子邮件(因为它与各个型号具有一对多的关系。
现在,如果您想到正确的实现方式,则可以使phone_number
和cont_email
只读字段,以便仅在读取而不是在写入时使用它:
class CrmContactSerializer(serializers.ModelSerializer):
phone_number = PhoneNumberSerializer(source = 'contact_number', read_only=True)
cont_email = ContactEmailSerializer(source = 'contact_email', read_only=True)
class Meta:
model = RestaurantContactAssociation
fields = ('id','phone_number','cont_email','contact')
这样,可以处理电话号码和连续电子邮件的验证错误。