2015-11-22 6 views
11

Sono nuovo di DRF e ho appena iniziato a creare un'API. Ho due modelli, un modello figlio collegato a un modello padre con una chiave esterna. Ecco la versione semplificata del modello che ho:Rapporti Serializer del resto di Django Rest: Come ottenere l'elenco di tutti gli oggetti figlio nel serializzatore del genitore?

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) 

Per creare serializzatori, ho seguito il DRF Serializer Relations e li ho creato come il seguente:

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') 

Sto cercando di ottenere il elenco di tutti i bambini nel serializzatore del genitore. Quello che voglio è essere in grado di ottenere una risposta del genere:

{ 
    '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'}, 
     ... 
    ], 
} 

non mi aspettavo questo a lavorare poiché non v'è alcun legame tra genitore e figlio nel modello Parent, but it is the suggested way to do it in the documentation, e non ha fatto lavoro.

sto ottenendo il seguente messaggio di errore:

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'. 

Penso che sia perfettamente ragionevole, ma non riuscivo a capire cosa mi manca qui.

Come posso ottenere l'elenco di tutti i bambini nel serializzatore del genitore?

+0

Credo che il nome correlato per una relazione all'indietro sia impostato su '{field_name} _set', quindi in questo caso' children_set'. Dovresti riuscire a sostituire 'children' con' children_set' nel tuo 'ParentSerializer' – jnishiyama

risposta

12

Penso che il tuo problema è che ti sei dimenticato di aggiungere uno related_name per il tuo modello di bambini. Avrei i modelli come questo:

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) 

E penso che con questo cambiamento si risolverà l'errore vostro ottenere

+2

Grazie! Esso funziona magicamente. – hnroot

9

È possibile implementare questo in due modi:

  1. Con SerializerMethodField: il codice è diventato in questo modo:

    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. Ogni campo potrebbe essere attributo del modello o un metodo, in modo da poter definire un metodo get_children_list in Parent modello, quindi chiamare in lista di campi di ParentSerializer:

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

Nota: È necessario eredita da serializers.ModelSerializer in questo scenario

+0

Grazie per la risposta. Per il primo, ottengo lo stesso errore: ** L'oggetto 'Parent' non ha attributo 'child_list' **. – hnroot

+0

Ho detto che child_list è un metodo della classe Parent che restituisce l'elenco dei bambini –

+0

Puoi anche ottenere il set di bambini da obj.children_set.all() –

Problemi correlati