10

I'm trying to use the "select_related" queryset method with DRF serializers, but this example is still doing a lot of sql queries.

How can I get the related object "model_b" from select_related method?

class Model_A(models.Model):
    title = models.CharField(max_length=100)
    description = models.TextField()
    model_b = models.ForeignKey(Model_B, null=True, blank=True)

class Model_B(models.Model):
    title = models.CharField(max_length=100)


class Model_A_Serializer(serializers.ModelSerializer):
    model_b = Model_B_Serializer(source="model_b")
    class Meta:
        model = Model_A
        fields = ('title', 'model_b')

class Model_B_Serializer(serializers.ModelSerializer):
    class Meta:
        model = Model_B


class Model_A_View(viewsets.ModelViewSet):
    serializer_class = Model_A_Serializer
    queryset = Model_A.objects.select_related('model_b').all()
Benyamin Jafari
  • 27,880
  • 26
  • 135
  • 150
Dilvane Zanardine
  • 2,118
  • 3
  • 23
  • 23
  • There may be some problem with your actual code, but it should work fine as written above. I'd need more info. – Scott Stafford Sep 18 '15 at 13:59
  • 1
    I'm voting to close this question as off-topic because you haven't included the SQL queries you're getting. Based on what you've written your code should work fine. – YPCrumble Jan 18 '18 at 22:18

1 Answers1

6

Use prefetch_related instead.

queryset = Model_A.objects.all().prefetch_related('model_b')

Also, you can log your sql queries to the console with this answer

Community
  • 1
  • 1
Ross Rogers
  • 23,523
  • 27
  • 108
  • 164
  • 1
    prefetch_related isn't better applied to ManyToMany relationships? – Dilvane Zanardine Jun 22 '15 at 21:54
  • 1
    I use it on ForeignKeys, ManyToMany, and inferred other-model `related_name` fields. In debug mode, I print out all my sql queries. When I used `prefetch_related` then all my tiny little one-entry requests on other models go away. It only does one query on the related FK'd models with a large number of ids. – Ross Rogers Jun 22 '15 at 22:12
  • 8
    `select_related` should work fine in your situation They behave a little differently: `select_related` will include model_b's in the original query via join, `prefetch_related` will run a single separate query for the model_b's using `WHERE ... IN ()`. – Scott Stafford Sep 18 '15 at 13:59