django rest框架序列化字典而不创建模型

Posted

技术标签:

【中文标题】django rest框架序列化字典而不创建模型【英文标题】:django rest framework serialize a dictionary without create a model 【发布时间】:2019-11-10 04:28:00 【问题描述】:

我的数据是这样的,我想序列化它们而不为它们创建模型。

[
  'form': 1, 'count': 1,
  'form': 2, 'count': 3
]

序列化到

[
  'form': 'my form name 1', 'count': 1,
  'form': 'my form name 2', 'count': 3
]

我想用序列化器对其进行序列化,通过pk获取form name form model。

class EavForm(models.Model):
    name = models.CharField(max_length=300)
    order = models.IntegerField(default=1)


# serializer
class CustomSerializer(serializers.Serializer):
    form = serializers.PrimaryKeyRelatedField(queryset=EavForm.objects.all())
    count = serializers.IntegerField()

一些错误,例如'int' object has no attribute 'pk'

在python控件中测试

d = ['form': 1, 'count': 1, 'form': 2, 'count': 1]
s = CustomSerializer(d, many=True)
print(s.data)

# error
Traceback (most recent call last):
  File "backend/src/db_tools/del1.py", line 25, in <module>
    print(s.data)
  File "backend/lib/python3.7/site-packages/rest_framework/serializers.py", line 768, in data
    ret = super(ListSerializer, self).data
  File "backend/lib/python3.7/site-packages/rest_framework/serializers.py", line 262, in data
    self._data = self.to_representation(self.instance)
  File "backend/lib/python3.7/site-packages/rest_framework/serializers.py", line 686, in to_representation
    self.child.to_representation(item) for item in iterable
  File "backend/lib/python3.7/site-packages/rest_framework/serializers.py", line 686, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "backend/lib/python3.7/site-packages/rest_framework/serializers.py", line 530, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "backend/lib/python3.7/site-packages/rest_framework/relations.py", line 272, in to_representation
    return value.pk
AttributeError: 'int' object has no attribute 'pk'

【问题讨论】:

这样的错误?为什么不发布带有完整回溯的实际错误? 好的,我把它们都贴在上面了。 【参考方案1】:

您想要的,可以通过以下更改来实现。

class EavForm(models.Model):
    name = models.CharField(max_length=300)
    order = models.IntegerField(default=1)


# serializer
class EvaFormPKRelatedField(PrimaryKeyRelatedField):
    def get_queryset(self):
        return EavForm.objects.all()

    def to_representation(self, value):
        return value.name


class CustomSerializer(serializers.Serializer):
    form = EvaFormPKRelatedField()
    count = serializers.IntegerField()

# Assume EvaForm exist of id 1 and 2
data = ['form': 1, 'count': 1, 'form': 2, 'count': 1]
s = CustomSerializer(data=data, many=True)
print(s.data) 
""" Output
[
  'form': 'my form name 1', 'count': 1,
  'form': 'my form name 2', 'count': 3
]
"""

print(s.validated_data)
""" Output
[
  'form': <EvaForm: Evaform object (1)>, 'count': 1,
  'form': <EvaForm: Evaform object (2)>, 'count': 3
]
"""

请注意,.data.validated_data 的输出有所变化。

    .data 将通过调用 .to_representation() 方法为您提供 PrimaryKeyRelatedField 的值。

    .validated_data 将通过调用 .to_internal_value() 方法为您提供 PrimaryKeyRelatedField 的值。因为,经过验证的数据通过调用它的所有验证来获取每个字段的值,并且在内部运行验证之前,每个字段值将通过调用它的 to_internal_value() 方法进行更新,并且该值用于验证过程。

【讨论】:

以上是关于django rest框架序列化字典而不创建模型的主要内容,如果未能解决你的问题,请参考以下文章

python Django Rest_Framework框架 模型类序列化器(ModelSerializer)详解(图文并茂版)

python Django Rest_Framework框架 模型类序列化器(ModelSerializer)详解(图文并茂版)

Django rest框架序列化字典

将不在模型中的字段添加到 Django REST 框架中的序列化程序

Django rest框架 - 模型序列化程序不会序列化所有字段

使用 Django REST 框架从多个模型返回结果