mam następujące modele:Optymalizacja zapytań do bazy danych w Django REST ramach
class User(models.Model):
name = models.Charfield()
email = models.EmailField()
class Friendship(models.Model):
from_friend = models.ForeignKey(User)
to_friend = models.ForeignKey(User)
a te modele są używane w poniższym widoku i serializatora:
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
Więc w zasadzie dla każdego użytkownika zwrócone przez widok GetAllUsers
, chcę wydrukować, czy użytkownik jest przyjacielem z requesterem (faktycznie powinienem sprawdzić zarówno od_, jak i do znajomego, ale nie ma to znaczenia dla pytania w punkcie)
co widzę jest to, że dla użytkowników n, w bazie danych, jest 1 zapytanie do uzyskania wszystkich użytkowników n, a następnie 1xn zapytań w serializer na get_is_friend_already
Czy istnieje sposób aby tego uniknąć w drodze reszta-ramowej ? Może coś jak przekazanie zapytania dołączonego do serializera z odpowiednimi wierszami Friendship
?
+1 Świetna odpowiedź Kevin! – Fiver
Świetna odpowiedź Kevin. Wielkie dzięki. Jedyny mały ammend jest to, że zamiast dla przyjaciela w obj.friends, musiałem zadzwonić: dla przyjaciela w obj.friends.all() .. odpowiedni wątek jest tutaj: http://stackoverflow.com/questions/6314841/ typeerror-relatedmanager-object-is-not-iterable – dowjones123
Pierwsze podejście z "prefetch_related" byłoby uciążliwe, gdyby użytkownik miał tysiące przyjaciół. W takim przypadku lepiej byłoby po prostu n zapytań dla każdego użytkownika – xleon