我正在使用Django 2.x
和Django REST Framework
。
我有两个模型
class Contact(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.ForeignKey(User, on_delete=models.PROTECT)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100, blank=True, null=True)
modified = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class AmountGiven(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
contact = models.ForeignKey(Contact, on_delete=models.PROTECT)
amount = models.FloatField(help_text='Amount given to the contact')
given_date = models.DateField(default=timezone.now)
created = models.DateTimeField(auto_now=True)
serializer.py 文件的序列化程序定义为
class ContactSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Contact
fields = ('id', 'first_name', 'last_name', 'created', 'modified')
class AmountGivenSerializer(serializers.ModelSerializer):
contact = ContactSerializer()
class Meta:
model = AmountGiven
depth = 1
fields = (
'id', 'contact', 'amount', 'given_date', 'created'
)
views.py
class AmountGivenViewSet(viewsets.ModelViewSet):
serializer_class = AmountGivenSerializer
def perform_create(self, serializer):
save_data = {}
contact_pk = self.request.data.get('contact', None)
if not contact_pk:
raise ValidationError({'contact': ['Contact is required']})
contact = Contact.objects.filter(
user=self.request.user,
pk=contact_pk
).first()
if not contact:
raise ValidationError({'contact': ['Contact does not exists']})
save_data['contact'] = contact
serializer.save(**save_data)
但是,当我向 AmountGiven 模型添加新记录并在
contact
字段中传递contact
id时它给出了错误
{"contact":{"non_field_errors":["Invalid data. Expected a dictionary, but got str."]}}
当我从 AmountGivenSerializer 中删除
contact = ContactSerializer()
时,它可以按预期工作,但是作为响应,由于depth
设置为1,因此联系人数据仅包含模型字段,而没有定义其他属性字段。
最佳答案
我不是这种请求解析模式的忠实拥护者。据我了解,您希望在检索AmountGiven
对象时能够查看所有联系人的详细信息,同时能够仅通过提供联系人ID来创建和更新AmountGiven
。
因此,您可以将AmountGiven
序列化程序更改为contact
model字段具有2个字段。像这样:
class AmountGivenSerializer(serializers.ModelSerializer):
contact_detail = ContactSerializer(source='contact', read_only=True)
class Meta:
model = AmountGiven
depth = 1
fields = (
'id', 'contact', 'contact_detail', 'amount', 'given_date', 'created'
)
请注意,
contact_detail
字段具有source
属性。现在,用于创建和更新的默认功能应该可以立即使用(验证和所有功能)。
当您检索
AmountGiven
对象时,您应该在contact_detail
字段中获取联系人的所有详细信息。更新
我想念您需要检查
Contact
是否属于用户(但是,我在user
模型上看不到Contact
字段,也许您错过了发布)。您可以简化该检查:class AmountGivenViewSet(viewsets.ModelViewSet):
serializer_class = AmountGivenSerializer
def perform_create(self, serializer):
contact = serializer.validated_data.get('contact')
if contact.user != self.request.user:
raise ValidationError({'contact': ['Not a valid contact']})
serializer.save()
关于django - 无效数据。需要字典,但在Django Rest Framework中的序列化程序字段出现str错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52867960/