Tengo una clase DRF ModelSerializer que serializa un modelo de Order . Este serializador tiene un campo:
num_modelA = serializers.SerializerMethodField() `
def get_num_modelA(self, o): r = ModelA.objects.filter(modelB__modelC__order=o).count() return r Donde ModelA tiene un campo ForeignKey modelB , ModelB tiene un campo ForeignKey modelC y ModelC tiene un campo ForeignKey order .
El problema con esto es, obviamente, que para cada pedido que se serializa, realiza una consulta adicional a la base de datos, lo que ralentiza el rendimiento.
Implementé un método estático setup_eager_loading como se describe aquí que solucionó el problema de consulta N+1 para otros campos que tenía.
@staticmethod def setup_eager_loading(queryset): # select_related for "to-one" relationships queryset = queryset.select_related('modelD','modelE') return queryset Mi idea era que también podía usar prefetch_related para reducir la cantidad de consultas. Pero no estoy seguro de cómo hacerlo, ya que Order y ModelA están separados por varias claves externas. Déjame saber si cualquier otra información sería útil
Puedes trabajar con una anotación:
from django.db.models import Count # … @staticmethod def setup_eager_loading(queryset): # select_related for "to-one" relationships return queryset.select_related('modelD','modelE').annotate( num_modelA=Count('modelC__modelB__modelA') ) en el serializador de su Order , puede usar num_modelA como IntegerField :
from rest_framework import serializers class OrderSerializer(serializers.ModelSerializer): num_modelA = serializers. IntegerField() class Meta: model = Order fields = [ 'num_modelA' , 'and', 'other', 'fields']