class Book(models.Model):
title = models.CharField(max_length=32)
author = models.ForeignKey("Author", on_delete=models.CASCADE)
publisher = models.ForeignKey(
"Publisher",
on_delete=models.CASCADE,
related_name="books",
)
class Publisher(models.Model):
address = models.CharField(max_length=32)
class AuthorType(DjangoObjectType):
class Meta:
model = Author
class BookType(DjangoObjectType):
class Meta:
model = Book
class PublisherType(DjangoObjectType):
class Meta:
model = Publisher
}}}
Fill in the database:
{{{
with transaction.atomic():
authors = Author.objects.bulk_create([
Author(name=f"Name{i}") for i in range(10)
])
publishers = Publisher.objects.bulk_create([
Publisher(address=f"Address{i}") for i in range(10)
])
Book.objects.bulk_create([
Book(
title=f"Title{i}",
author=random.choice(authors),
publisher=random.choice(publishers),
) for i in range(20)
])
}}}
GraphQL query:
{{{
{
publishers {
address
books {
title
author {
name
}
}
}
}
}}}
22 db queries:
{{{
class Query(graphene.ObjectType):
publishers = graphene.List(PublisherType)
def resolve_publishers(self, info):
queryset = Book.objects.select_related("author").only("title",
"author__name")
return Publisher.objects.prefetch_related(Prefetch("books",
queryset)).only("address")
}}}
2 db queries:
{{{
class Query(graphene.ObjectType):
publishers = graphene.List(PublisherType)
def resolve_publishers(self, info):
queryset = Book.objects.select_related("author").only("title",
"author__name", "publisher_id")
return Publisher.objects.prefetch_related(Prefetch("books",
queryset)).only("address")
}}}
I fixed function **prefetch_related_objects** at django/db/models/query.py
and now I don't need **publisher_id** in **only** method:
{{{
...
prefetcher, descriptor, attr_found, is_fetched = get_prefetcher(
first_obj, through_attr, to_attr
)
from django.db.models.fields.related_descriptors import
ReverseManyToOneDescriptor
if type(descriptor) is ReverseManyToOneDescriptor:
lookup.queryset.query.deferred_loading[0].add(descriptor.field.attname)
if not attr_found:
raise AttributeError(
...
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/33835>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* Attachment "PR1.PNG" added.
* Attachment "PR2.PNG" added.