我有以下標準通用外鍵的字段的模型:
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')
這工作正常,但在其他兩個相關的情況下,我不能得到的東西工作:
- 我想用
HyperlinkedRelatedField
。該字段需要view_name參數,這是我無法聲明的,因爲視圖名稱因相關模型而異。我通過使用SerializerMethodField
來解決這個問題,在運行時實例化一個HyperlinkedIdentityField
並返回它的field_to_native
方法(請參閱下面的代碼片段)。這不覺得很優雅。 - 我想通過說
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)
請注意,如果源與字段名稱不同,則只需對字段使用「source」參數。你可以把它放在'event_object'的情況下。 –