django - 无效数据。需要字典,但在Django Rest Framework中的序列化程序字段出现str错误

标签 django django-rest-framework django-serializer

我正在使用Django 2.xDjango 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时

enter image description here

它给出了错误
{"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/

相关文章:

django-rest-framework - 在 Django Rest Framework 中,如何添加 ManyToMany 相关对象?

django - 如何在没有 read_only=True 的情况下在 django rest 框架中使用 Foreign_Key 值而不是 id

python - 如何在 Django 中序列化后构建对象

django Restframework token 身份验证失败,错误代码为 "invalid token"

python - Django Rest框架: passing queryset to Response()

python - Django 单元测试;使用 python-social-auth 登录

django - 自定义 Wagtail 权限

python - 按照第一个 Django 应用程序教程,我无法执行 runserver 命令

django - gunicorn、nginx 和使用端口 80 运行 django web 应用程序

django - Django REST Framework部分更新和验证