2017-09-18 9 views
0

のネストされた直列化を最適化する私はこのようなモデルとシリアライザがあります、私の見解ではジャンゴRESTフレームワーク - クエリセット

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) 
    #... 

デバッグツールバーを開くと、カレンダーイベントごとにデータベースがリマインダーテーブルを2回ヒットすることがわかります。

enter image description here

質問は、この動作を最適化できるか、です。

答えて

0

最もストレートな方法は、あなたのビューでCalendarEventsのCalendarEventRemindersをプリフェッチすることになります。CalendarEventsを取得中

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

これは、すべてのCalendarEventRemindersをプリフェッチします。

これは、select_related()のようにSQL結合をトリガーしないことに注意してください。この場合、我々は関係を逆にしているので、select_related()を使用することはできません。 :)

Django Docs regarding prefetch_relatedをチェックしてください。

+0

まあ、私は 'prefetch_related'について知っています。問題は、ネストされたシリアライザを使ってどうすればいいのかということでした。クエリーセットではなくオブジェクトのみをシリアライズすることを意図していますか? –

+0

はい、シリアライザはオブジェクトのみをシリアル化します。クエリーセットの処理はあなたの視点で行われます。デバッグツールバーに表示されるクエリは、クエリセットへの単純な '__getitem__'呼び出しによってトリガされます。そのため、' prefetch_related'がそれらのクエリを排除するか、むしろ最初からすべてを一度に取得します。 – olieidel

関連する問題