Django REST框架 - 优化查询集的嵌套序列化

时间:2017-09-18 23:22:49

标签: django-rest-framework

我有一个这样的模型和序列化器:

models.py

class CalendarEvent(BaseMixin):
    title = models.TextField(blank=True, null=True)

class CalendarEventReminder(BaseMixin):
     event = models.ForeignKey(CalendarEvent, related_name = 'reminders')
     minutes = models.CharField()

class Meta:
    managed = False
    db_table = 'calendar_event_reminder'

def __str__(self):
    return self.minutes

serializer.py

class CalendarEventSerializer(serializers.ModelSerializer):
    reminders = serializers.StringRelatedField(many=True)

    class Meta:
        model = CalendarEvent
        fields = ('title', 'reminders')

在我看来,我会做以下事情:

def test(request):
    #...
    event = CalendarEvent.objects.filter(id__in = [930, 935])
    serializer = CalendarEventSerializer(event, many = True)
    print (serializer.data)
    #...

当我打开调试工具栏时,我发现数据库会针对每个日历事件两次点击提醒表。

enter image description here

问题是,如何优化此行为。

1 个答案:

答案 0 :(得分:1)

最直接的方法是在视图中预取CalendarEvent的CalendarEventReminders:

# views.py
def get(request):
    event = CalendarEvent.objects.filter(id__in = [930, 935]) \
                                 .prefetch_related('reminders')
    # ...

这将在获取CalendarEvents时预取所有CalendarEventReminders。

请注意,这不会触发select_related()之类的SQL连接。在这种情况下,我们无法使用select_related(),因为我们会向后关注这种关系。 :)

查看Django Docs regarding prefetch_related