2013-01-21 50 views
11

問題Django的REST框架和通用的關係

我有以下標準通用外鍵的字段的模型:

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參數,這是我無法聲明的,因爲視圖名稱因相關模型而異。我通過使用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) 
+1

請注意,如果源與字段名稱不同,則只需對字段使用「source」參數。你可以把它放在'event_object'的情況下。 –

回答

8

您的權利,REST框架不支持那些使用案例,它不是明顯對我什麼設計看起來像是如此。你可能需要模型 - >視圖(用於超鏈接的情況)和模型 - >串行器(用於嵌套的情況)的隱式註冊表,我認爲我不會很熱衷。

執行您所需要的最簡單方法可能是子類ManyRelatedField並創建一個自定義字段類型,覆蓋to_native(self, obj)以按照您希望的方式序列化該集合中的每個對象。

+0

謝謝你的理智檢查湯姆。我沒有問過一個問題,它有一個「正確的」答案(可憐的形式),但是你認爲你的腦袋或多或少碰到了釘子。乾杯。 –