2015-11-22 57 views
11

我是DRF的新手,剛剛開始構建API。我有兩個模型,一個用外鍵連接到父模型的子模型。這裏是模型我的簡化版本:Django Rest Framework序列化程序關係:如何獲取父級序列化程序中所有子對象的列表?

class Parent(models.Model): 
    name = models.CharField(max_length=50) 


class Child(models.Model): 
    parent = models.ForeignKey(Parent) 
    child_name = models.CharField(max_length=80) 

要創建序列化,我跟着DRF Serializer Relations,我已經創造了他們爲以下幾點:

class ChildSerializer(serializers.HyperlinkedModelSerializer): 

    parent_id = serializers.PrimaryKeyRelatedField(queryset=Parent.objects.all(),source='parent.id') 

    class Meta: 
     model = Child 
     fields = ('url','id','child_name','parent_id') 

    def create(self, validated_data): 
     subject = Child.objects.create(parent=validated_data['parent']['id'], child_name=validated_data['child_name']) 

     return child 


class ParentSerializer(serializers.HyperlinkedModelSerializer): 
    children = ChildSerializer(many=True, read_only=True) 
    class Meta: 
     model = Course 
     fields = ('url','id','name','children') 

我試圖讓父母序列化程序中所有孩子的列表。我想是能夠得到這樣的迴應:

{ 
    'url': 'https://dummyapidomain.com/parents/1/', 
    'id': '1', 
    'name': 'Dummy Parent Name', 
    'cildren': [ 
     {'id': 1, 'child_name': 'Dummy Children I'}, 
     {'id': 2, 'child_name': 'Dummy Children II'}, 
     {'id': 3, 'child_name': 'Dummy Children III'}, 
     ... 
    ], 
} 

我沒想到這個工作,因爲在父模型,but it is the suggested way to do it in the documentation父母和孩子之間沒有任何聯繫,也沒有工作。

我收到以下錯誤信息:

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

我認爲這是完全合理的,但我不明白我在這裏失蹤。

如何獲取父級序列化程序中所有子級的列表?

+0

我相信反向關係的相關名稱默認爲'{field_name} _set',所以在這種情況下'children_set'。你應該可以在'ParentSerializer'中用'children_set'替換'children'' – jnishiyama

回答

12

我認爲你的問題是你忘了爲你的兒童模型添加一個related_name。我想有這樣的模式:

class Parent(models.Model): 
    name = models.CharField(max_length=50) 

class Child(models.Model): 
    parent = models.ForeignKey(Parent, related_name='children') # <--- Add related_name 
    child_name = models.CharField(max_length=80) 

而且我認爲這種變化,將解決你獲得

+2

謝謝!它像一個魅力。 – hnroot

9

錯誤您可以通過兩種方式實現這一點:

  1. 隨着SerializerMethodField:您的代碼變成這樣:

    class ParentSerializer(serializers.ModelSerializer): 
    
        children_list = serializers.SerializerMethodField('_get_children') 
    
        def _get_children(self, obj): 
         serializer = ChildSerializer(obj.child_list(), many=True) 
         return serializer.data 
    
        class Meta: 
         model = Course 
         fields = ('url','id','name','children_list') 
    
  2. 每場可以是模型或方法的屬性,這樣你就可以在Parent模型定義get_children_list方法,然後調用它的ParentSerializer字段列表:

    class ParentSerializer(serializers.ModelSerializer): 
    
        class Meta: 
         model = Course 
         fields = ('url','id','name','get_children_list') 
    

注意:您需要從以繼承serializers.ModelSerializer在這種情況下

+0

感謝您的回答。對於第一個,我得到了同樣的錯誤:**'Parent'對象沒有屬性'child_list'**。 – hnroot

+0

我說過,child_list是你的父類中返回兒童列表的方法 –

+0

你也可以通過obj.children_set.all() –

相關問題