2016-11-18 31 views
0

一個函數作爲源我有以下型號:執行在Django的串行

class A(Model): 
    pass 

class B(Model): 
    a = ForeignKey(A, related_name = 'b') 
    b_field = CharField(max_length=64) 

,我現在想序列化的目的,在其中我想有第一個B對象。我曾經有過這樣的代碼:

class BSerializer(ModelSerializer): 

    class Meta: 
     model = B 
     fields = '__all__' 

class ASerializer(ModelSerializer): 
    b = BSerializer(source='b.first') 

    class Meta: 
     model = A 
     fields = '__all__' 

這用來工作,但現在我的單元測試失敗:

AttributeError: Got AttributeError when attempting to get a value for field `b_field` on serializer `BSerializer`. 
The serializer field might be named incorrectly and not match any attribute or key on the `method` instance. 
Original exception text was: 'function' object has no attribute 'b_field'. 

顯然,b.first是一個函數,而且確實也沒有這樣的屬性。然而,我希望源字段能夠執行該功能。我嘗試了以下線路:

b = BSerializer(source='b.first') 

但是這給了符合以下錯誤:

AttributeError: Got AttributeError when attempting to get a value for field `b` on serializer `ASerializer`. 
The serializer field might be named incorrectly and not match any attribute or key on the `A` instance. 
Original exception text was: 'RelatedManager' object has no attribute 'first()'. 
  1. 有這種行爲最近已改變了嗎?
  2. 如何取第一個b對象進行序列化?

回答

1

各地source的規格並沒有改變,因爲你可以在doc閱讀:

source : The name of the attribute that will be used to populate the field. May be a method that only takes a self argument, such as URLField(source='get_absolute_url') , or may use dotted notation to traverse attributes, such as EmailField(source='user.email') .

所以,你應該傳遞一個:attr或方法的名稱,其實例被序列化類的,在你的情況A,或attr或方法來遍歷屬性(帶點符號),但始終從A類的attr /方法開始。

所以,你可以解決你的問題是這樣的:

class A(Model): 
    def first_b(self): 
     return self.b.first() 


class ASerializer(ModelSerializer): 
    b = BSerializer(source='first_b') 

    class Meta: 
     model = A 
     fields = '__all__ 
+1

這就像一個魅力,謝謝! :-D – physicalattraction