2015-04-15 3 views
4

У меня есть базовая настройка с использованием Django Rest Framework. У меня есть две модели и вложенные установки сериализатора:Django Rest Framework вложенный сериализатор, не показывающий связанные данные

# models.py 

from django.db import models 

class Plan(models.Model): 
    name = models.CharField(max_length='100') 

    def __unicode__(self): 
     return u'%s' % (self.name) 

class Group(models.Model): 
    plan = models.ForeignKey('plan') 
    name = models.CharField(max_length='50') 
    weight = models.SmallIntegerField() 

    def __unicode__(self): 
     return u'%s - %s' % (self.name, self.plan.name) 


# serializer.py 

from plans.models import Plan, Group 
from rest_framework import serializers 

class GroupSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Group 
     fields = ('name', 'weight') 

class PlanSerializer(serializers.ModelSerializer): 
    group = GroupSerializer(many=True, read_only=True) 

    class Meta: 
     model = Plan 
     fields = ('name', 'group') 


# views.py 

from rest_framework import viewsets 

from plans.models import Plan 
from plans.serializers import PlanSerializer 

class PlanViewSet(viewsets.ModelViewSet): 
    queryset = Plan.objects.all() 
    serializer_class = PlanSerializer 

Когда я рассматриваю сериализаторы отношение в Shell Джанго он показывает отношение правильно:

PlanSerializer(): 
name = CharField(max_length='100') 
group = GroupSerializer(many=True, read_only=True): 
    name = CharField(max_length='50') 
    weight = IntegerField() 

То, что я в конечном итоге получить обратно через завиток:

[ 
    { 
     name: Test Plan 
    } 
] 

Что я ожидаю, чтобы получить обратно:

[ 
    { 
     name: Test Plan, 
     group: [ 
       { 
        name: Test Group, 
        weight: 1 
       } 
     ] 
    } 
] 

Вложенные данные не поступают. Я теряюсь за то, что я здесь неправильно настроил. Может ли кто-нибудь указать мне в правильном направлении?

ответ

6

Проблема возникает из-за вашего queryset: queryset = Plan.objects.all(). Ни один из элементов в этом queryset не имеет атрибута .group, поэтому ваш результат пуст. По умолчанию Django создает обратное отношение plan ForeignKey называется group_set (если вы не переименовать его через related_name) (это означает, что каждый plan элемента в queryset имеет атрибут group_set который является QuerySet, содержащим все группы этого plan). Вы можете использовать этот атрибут, чтобы получить правильную сериализацию. Это означает, что для изменения:

class PlanSerializer(serializers.ModelSerializer): 
    group_set = GroupSerializer(many=True, read_only=True) 

    class Meta: 
     model = Plan 
     fields = ('name', 'group_set') 

Если вы действительно хотите придерживаться group(кстати, это очень плохое имя для списка групп). Вы можете взломать его с prefetch_related так:

queryset = Plan.objects.prefetch_related('group_set', to_attr='group') 

таким образом каждый plan деталь будет иметь атрибут group - а queryset, содержащие все группы для этого plan.

+1

Оцените справку. Я изменился на 'group_set', поскольку я не был связан с именем и исправил его. Я также рассмотрю изменение имени из 'group' в' categories' или что-то в этом роде. – land0

+0

Вы можете изменить стандартную xxx_set-нотацию в тот момент, когда вы определяете FK через 'related_name', например. 'plan = models.ForeignKey ('plan', related_name = 'groups')'. Теперь у вас не будет атрибута «group_set», кроме «групп». – Todor

+0

Это действительно помогло мне найти причину моей собственной проблемы. Я бы предложил добавить ваш последний комментарий Todor к вашему ответу как имеющий надлежащие связанные_имя в вашей модели, которые может использовать сериализатор, кажется гораздо более полным ответом. – Animal451

Смежные вопросы