Ho i seguenti modelli:Ottimizzazione delle query di database in quadro Django REST
class User(models.Model):
name = models.Charfield()
email = models.EmailField()
class Friendship(models.Model):
from_friend = models.ForeignKey(User)
to_friend = models.ForeignKey(User)
E quei modelli sono utilizzati nella seguente vista e serializzatore:
class GetAllUsers(generics.ListAPIView):
authentication_classes = (SessionAuthentication, TokenAuthentication)
permission_classes = (permissions.IsAuthenticated,)
serializer_class = GetAllUsersSerializer
model = User
def get_queryset(self):
return User.objects.all()
class GetAllUsersSerializer(serializers.ModelSerializer):
is_friend_already = serializers.SerializerMethodField('get_is_friend_already')
class Meta:
model = User
fields = ('id', 'name', 'email', 'is_friend_already',)
def get_is_friend_already(self, obj):
request = self.context.get('request', None)
if request.user != obj and Friendship.objects.filter(from_friend = user):
return True
else:
return False
Quindi, in pratica, per ogni utente restituito dalla vista GetAllUsers
, voglio stampare se l'utente è un amico con il richiedente (in realtà dovrei controllare entrambi da_ e to_friend, ma non ha importanza per la domanda in questione)
Quello che vedo è che per N utenti nel database, v'è 1 query per ottenere tutti gli utenti N, e le query poi 1XN nel del serializzatore get_is_friend_already
C'è un modo per evitare questo nel modo di riposo-quadro ? Forse qualcosa come passare una query inclusa a select_related
al serializzatore che ha le righe rilevanti Friendship
?
+1 Grande risposta di Kevin! – Fiver
Ottima risposta Kevin. Molte grazie. L'unica piccola ammenda è che invece di un amico in obj.friends, avevo bisogno di chiamare: per amico in obj.friends.all() .. il thread corrispondente è qui: http://stackoverflow.com/questions/6314841/ typeerror-relatedmanager-object-is-iterable – dowjones123
Il primo approccio con "prefetch_related" sarebbe ingombrante se l'utente avesse migliaia di amici. In tal caso sarebbe meglio fare solo n query per ogni utente. – xleon