This is a very good question for no obvious problem. The assumptions you make about learning Django and the related DRF plugins when reading the official documentation will create a conceptual model that is simply not true. I am saying here that Django, explicitly designed for relational databases, does not do it quickly out of the box!
problem
The reason for slow Django / DRF when querying a model that contains one-to-many relationships in the ORM world is known as the N + 1 ( N + 1 , N + 1 ) problem and is especially noticeable when ORM uses lazy loading - Django uses lazy loading !!!
example
Suppose you have a model that looks like this: the reader has many books . Now you would like to get all the books with the title that the hardcore reader read. In Django, you accomplish this by interacting with ORM in this way.
Under the hood. The first Reader.objects.filter(type='hardcore') statement will create a single SQL query similar to this one. We assume that it will return 100 records.
SELECT * FROM "reader" WHERE "reader"."type" = "hardcore";
Next, for each reader [reader.book.title for reader in readers] you should get related books. It will look something like this in SQL.
SELECT * FROM "book" WHERE "book"."id" = 1; SELECT * FROM "book" WHERE "book"."id" = 2; ... SELECT * FROM "book" WHERE "book"."id" = N;
What you have left is 1, select 100 readers, and N - get books -where N is the number of books. Thus, in total you have N + 1 database queries.
The consequence of this behavior is 101 database queries, which ultimately leads to extremely long loading times of a small amount of data and slows down Django!
Decision
The solution is easy, but not obvious. The following white papers for Django or DRF do not cover the issue. In the end, you follow best practices and end up with slow application.
To solve the problem of slow loading, you will have to upload your data to Django. This usually means using the appropriate prefetch_related () or select_related () method to build the SQL INNER JOIN on models / tables and retrieve all your data in just 2 queries instead of 101.
Related Readings
Lukasz Dynowski
source share