2016-09-29 39 views
0

我需要序列化的自參考層次差不多失去了:self.parent.parent .__ class__

class Systm(models.Model): 
    ... 
    parent = models.ForeignKey('self', on_delete=models.CASCADE, blank = True, null = True, related_name="children") 

,我是能夠實現與下面的代碼:

class RecursiveField(serializers.Serializer): 
    def to_representation(self, value): 
     serializer = self.parent.parent.__class__(value, context=self.context) 
     return serializer.data 

class SystmSerializer(serializers.ModelSerializer): 
    children = RecursiveField(many = True, read_only = True) 

    class Meta: 
     model = models.Systm 
     fields = ('id', 'name', 'type', 'children') 

它的工作原理除了我所做的只是複製和粘貼代碼,但並不知道它是如何工作的以及爲什麼它能夠工作。這很煩人,我想了解它。
我把'print'命令寫入'to_representation(...)',但仍不清楚。我瞭解到,'self.parent.parent.__class__(value, context=self.context)'執行時有遞歸,但不知道爲什麼。
如果有人能解釋給我,我會很感激。

感謝,

回答

0

這基本上通過工作獲取頂級序列化器類和instanciating它返回一個孩子的序列化值。序列化程序(或字段)的parent屬性是將其聲明爲字段的序列化程序實例。

self.parent是聲明many=True時隱式創建的列表序列化程序(請參見ListSerializer)。 self.parent.parentSystmSerializer實例。

我的猜測是,這段代碼只能工作,因爲遞歸字段已被聲明爲many=True。如果你有child = RecursiveField(read_only = True)代碼將是:

class RecursiveField(serializers.Serializer): 
    def to_representation(self, value): 
     serializer = self.parent.__class__(value, context=self.context) 
     return serializer.data 

爲了簡單,當你(或DRF)調用serialializer_instance.data,它對to_representation調用序列化對象實例。

遞歸做SystmSerializer.to_representation時發揮作用:

  1. to_representation(instance)被調用時,它會調用to_representation(field_instance)在各個領域。
  2. 其中一個領域是recursiveField,並更準確地與該recursiveField
  3. 呼籲ListSerializerto_representation相關的ListSerializer將調用recursiveField.to_representation(child)該實例的所有兒童(如果有的話)。
  4. 這是遞歸啓動時:的recursiveField.to_representation實施instanciates孩子Systm對象上一個新SystmSerializer實例,然後調用SystmSerializer.data本身觸發to_representation電話......你回來了,在一個新的SystmSerializer實例第1步孩子Systm對象。

當沒有孩子時遞歸結束。當然,如果一個孩子引用了祖先,你可能會遇到無窮無盡的遞歸。

+0

這基本上是正確的,雖然非常簡單,我不確定我會幫助OP真正理解所有其他框架魔法下面發生了什麼。 –

+0

嗨邁克爾,感謝您的回覆!不過,我擔心邁克爾是對的,我還沒有看到整個畫面。我沒有得到它如何遞歸圖片,爲什麼有遞歸呢?是否因爲django爲queryset的每個記錄調用了to_represantation(...)? – Viktor

+0

添加了簡單的描述如何發生遞歸,希望這有助於。 to_representation確實是在對象實例和所有孩子上調用的,等等...... –