gpt4 book ai didi

Django REST Framework 和通用关系

转载 作者:行者123 更新时间:2023-12-02 03:36:16 25 4
gpt4 key购买 nike

问题

我有一个具有以下标准通用外键字段的模型:

content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
event_object = generic.GenericForeignKey('content_type', 'object_id')

根据 REST 框架的文档,我可以执行以下操作来正确序列化:

class WhateverSerializer(serializers.ModelSerializer):
event_object = serializers.RelatedField(source='event_object')

这工作正常,但是在其他两种相关情况下,我无法让事情正常工作:

  1. 我想使用HyperlinkedRelatedField。该字段需要 view_name 参数,但我无法声明该参数,因为 View 名称因相关模型而异。我通过使用 SerializerMethodField 解决了这个问题,在运行时实例化 HyperlinkedIdentityField 并返回其 field_to_native 方法(请参阅下面的代码片段)。这感觉不太优雅。
  2. 我想通过 event_object = SoAndSoSerializer(source='event_object') 将相关对象直接嵌套在序列化中。我能看到的唯一解决方案是遍历我定义的每个 *Serializer 并检查哪个具有正确的模型,然后使用它。同样,这感觉不太优雅。

问题

HyperlinkRelatedField 是否适用于一般关系?我只是犯了一个错误吗?有没有一个明显的解决方案来选择我缺少的正确的*Serializer

代码片段

上面第 1 点提到的不优雅的解决方案:

class WhateverSerializer(DefaultSerializer):

event_object_url = serializers.SerializerMethodField('get_related_object_url')
# ...

def get_related_object_url(self, obj):
obj = obj.event_object
default_view_name = '%(model_name)s-detail'
format_kwargs = {
'app_label': obj._meta.app_label,
'model_name': obj._meta.object_name.lower()
}
view_name = default_view_name % format_kwargs
s = serializers.HyperlinkedIdentityField(source=obj, view_name=view_name)
s.initialize(self, None)
return s.field_to_native(obj, None)

最佳答案

你说得对,REST 框架不支持这些用例,而且对我来说,如果支持的话,设计会是什么样子并不明显。您可能需要模型-> View (对于超链接情况)和模型->序列化器(对于嵌套情况)的隐式注册表,我认为我不会非常热衷于此。

完成您需要的操作的最简单方法可能是子类化ManyRelatedField并创建自定义字段类型,覆盖to_native(self, obj)以序列化中的每个对象完全按照您想要的方式设置。

关于Django REST Framework 和通用关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14448764/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com