Django REST框架和通用关系

Ben*_*ham 12 django django-rest-framework

问题

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

content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
event_object = generic.GenericForeignKey('content_type', 'object_id')
Run Code Online (Sandbox Code Playgroud)

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

class WhateverSerializer(serializers.ModelSerializer):
    event_object = serializers.RelatedField(source='event_object')
Run Code Online (Sandbox Code Playgroud)

这工作正常,但在其他两个相关的情况下,我无法让事情奏效:

  1. 我想用HyperlinkedRelatedField.此字段需要view_name参数,这是我无法声明的,因为视图名称随相关模型而变化.我通过使用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)
Run Code Online (Sandbox Code Playgroud)

Tom*_*tie 8

你的权利,REST框架不支持这些用例,而且对我来说这并不是什么设计看起来会是什么样子.您可能需要一个隐式的模型 - >视图注册表(对于超链接的情况)和模型 - >序列化程序(对于嵌套的情况)我不认为我会非常热衷于此.

执行所需操作的最简单方法可能是子类化ManyRelatedField并创建自定义字段类型,重写to_native(self, obj)以完全按照您希望的方式序列化集合中的每个对象.