I'm try to decrease query counts for using prefetch_related and select_related . However, it seems doesn't work.
in Match Model have 5 ForeignKey fields, so when i get the query counts it will return 5. Also when i delete def get_queryset
method in MatchDetailAPIView
. The Api still work. ( eg 127.0.0.1:8000/game/match/match-1 is working whether or not the get_queryset
method.
I can't find where I'm doing wrong.
Models.py
class Game(models.Model):
name = models.CharField(max_length=255)
...
class Match(models.Model):
name = models.TextField(blank=False, null=False)
game = models.ForeignKey(Game, on_delete=models.SET_NULL, null=True)
tournament = models.ForeignKey(Tournament, on_delete=models.SET_NULL, null=True, blank=True)
....
serializers.py
class MatchSerializer(serializers.ModelSerializer):
class Meta:
model = Match
fields = '__all__'
#exclude = ['participant', ]
views.py
class MatchDetailAPIView(RetrieveAPIView):
serializer_class = MatchSerializer
def get_queryset(self):
queryset =Match.objects.all().prefetch_related('game_id')
return queryset
def get_object(self):
gameslug = self.kwargs.get('gameslug')
slug = self.kwargs.get('slug')
# find the user
game = Game.objects.get(slug=gameslug)
return Match.objects.get(slug=slug, game__slug=game.slug)
def get_serilizer_context(self, *args, **kwargs):
return {'request': self.request}
You should use select_related for ForeignKey
fields, since prefetch_related
does the joining in Python, and select_related
creates an SQL join.
You should also refer to the relationship by it's name, not the id of the ForeignKey ('game_id' vs. 'game'):
def get_queryset(self):
queryset =Match.objects.all().select_related('game')
return queryset
As mentioned in django docs , select_related should be used for foeign-key relationships. Also for RetrieveAPIView override the get method.
def get(self, request, *args, **kwargs):
gameslug = self.kwargs.get('gameslug')
slug = self.kwargs.get('slug')
game = Game.objects.get(slug=gameslug)
return Match.objects.filter(slug=slug, game__slug=gameslug).select_related('game').first()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.