django - 如何在 DRF 中序列化 GenericForeignKey?

标签 django django-rest-framework

我有一个模型,它使用通用外键使用“content_type”字段来存储内容类型和“object_id”来存储对象 ID。该模型需要使用 CRUD API 进行操作,而我正在使用 DRF。我有一个模型的序列化程序,但我遇到了一些问题。如果我只是将 content_type 添加到这样的字段列表中

类 MySerializer(ModelSerializer):
元类:
字段 = ('name', 'state', 'content_type', 'object_id')

序列化程序将 JSON 表示设置为 ContentType 模型实例的 ID。 API 的用户不知道这些 ID,我不想用另一个 API 公开 ContentType 模型。 API 用户确实知道他们想要链接的对象类型,因此他们可以发送内容类型名称。所以,我已经定义了这样的序列化器

类 MySerializer(ModelSerializer):
content_type = serializers.CharField(source="content_type.name")
元类:
字段 = ('name', 'state', 'content_type', 'object_id')

序列化模型工作得很好。如果我使用通用关系来链接 User 实例,我会得到类似 {'name': 'test', 'state': 'NY', 'content_type': 'user', 'object_id': 123} 的信息。 .但是当我使用 JSON 结构提交 PUT 或 POST 请求时,DRF 会将其转换为类似 {'name': 'test', 'state': 'NY', 'content_type': {'name': {'name': 'user'}}, 'object_id': 123} 的内容。 .我可以写一些类似的东西

def 创建(自我,validated_data):
ct_model =validated_data['content_type']['name']['name']
validate_data['content_type'] = ContentType.objects.get(model=ct_model)
返回 MyModel.objects.create(**validated_data)

但这似乎是随意和脆弱的。处理这种情况的正确方法是什么?

更新 #1:目前,我已经通过使用此代码覆盖 to_internal_value() 解决了问题

def to_internal_value(self, data):
content_type = data.get('content_type', None)
验证数据 = super ()。to_internal_value(数据)
尝试:
validate_data['content_type'] = ContentType.objects.get(model=content_type)
除了 ContentType.DoesNotExist:
raise serializers.ValidationError("无效的内容类型 %s"% content_type)
返回validated_data

显示相关对象似乎是一种丑陋的技巧。

最佳答案

您可能需要自定义,提供您自己的字段类 to_representationto_internal_value序列化这种关系的方法。没那么复杂,试试吧。

考虑使用 uri 符号 /api/resource/object_id作为您的序列化格式。

将内容类型转换为资源 uri 并返回可能有点挑战性(如果您有多个可能的类型),但我确信必须有一些简单的方法来做到这一点。

关于django - 如何在 DRF 中序列化 GenericForeignKey?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39004234/

相关文章:

javascript - 从 Axios 到 Django 的 400 错误请求,字段为必填项

django forms - 基于 get 请求 url 参数选择选项

python - Docker Compose 和 Django 生成器语法错误

mysql - djangos unique=true 实际上做了什么?

python - 使用嵌套对象在 ModelViewSet 上发布 Django Rest Framework

python - Django Rest 嵌套序列化器的 AttributeError

python - 将新的 django rest 框架应用程序添加到设置

django - 有没有办法用我的模型中的更改来更新数据库?

django-rest-framework - DjangoFilterBackend 字段 = null

python - django.contrib.auth.login() 函数不返回任何用户登录