2015-12-15 16 views
6

Mam nadrzędny i powiązany z nim model potomny i chciałbym renderować pola z potomka płaskiego w reprezentacji nadrzędnej (read only). Obecnie osiągnąłem to dzięki niestandardowej implementacji to_representation, ale wydaje się to bardzo zaangażowane i zastanawiam się, czy nie ma prostszego sposobu na osiągnięcie tego.Struktura spoczynkowa Django reprezentuje spłaszczony obiekt zagnieżdżony

Jest to bardziej skomplikowane, ponieważ mój powiązany model jest połączony za pośrednictwem nieruchomości.

Tak oto konkretny przykład: domyślnie powiązany obiekt będzie renderowane jak:

{ 
    parent_name:'Bob', 
    child:{ 
    name:'Alice' 
    } 
} 

To jest to, co chcę, a obecnie dostać się z moim to_representation:

{ 
    parent_name:'Bob',  
    child_name:'Alice' 
} 

Moje modele wygląda tak:

class ChildModel(models.Model): 
    name = models.CharField(max_length=100, null=True) 

class ParentModel(models.Model): 
    name = models.CharField(max_length=100, null=True) 
    _child = models.ForeignKey('ChildModel', null=True) 

    @property 
    def child(self): 
     return self._most_recent_status 

    @name.setter 
    def child(self, value): 
     self._child = value 

tutaj moje serializers:

class FlatChildField(serializers.RelatedField): 
    def to_representation(self, value): 
     return value.name 


class FlatParentSerializer(serializers.ModelSerializer):  
    parent_name = serializers.CharField(source='name', read_only=True) 
    child_name = FlatChildField(source='_child', read_only=True) 

    class Meta: 
     model = Parent 
     fields = ('name', 'child_name') 

Dla prostsze rozwiązanie, aby uzyskać płaską reprezentację powiązanych modeli byłbym wdzięczny.

Dla kompletności, chciałbym usłyszeć, jeśli istnieje prostsze rozwiązanie dla "normalnych" powiązanych modeli (tj. Również pól modelu właściwości). Szukałem odpowiednika składni zapytania modelu django z related_model__field, ale nie mogę tego znaleźć. Czy to istnieje dla frameworku django rest?

Dziękujemy

Odpowiedz

13

Najprostsze sposoby byłoby użyć source:

class FlatParentSerializer(serializers.ModelSerializer):  
    parent_name = serializers.CharField(source='name', read_only=True) 
    child_name = serializers.CharField(source='_child.name', read_only=True) 

class Meta: 
    model = Parent 
    fields = ('name', 'child_name') 
+0

To działa bardzo, dziękuję. –

+0

Działa to również bez read_only, co jest świetne do spłaszczania modeli zagnieżdżonych! – alekwisnia

3

Można użyć SerializerMethodField, to ratuje cię naprawdę dużo pracy i jest tak czyste i trywialne:

class FlatParentSerializer(serializers.ModelSerializer):  
    parent_name = serializers.CharField(source='name', read_only=True) 
    child_name = serializers.SerializerMethodField('get_child_name') 

    class Meta: 
     model = Parent 
     fields = ('name', 'child_name') 

    def get_child_name(self, obj): 
     return obj._child.name