N+1 #33
-
Hi. I have a question about N+1 that happens when using DjangoObjecttypes. Based on documentation problems https://github.com/graphql-python/graphene-django/blob/main/docs/authorization.rst#global-filtering DjangoObjectType has some problems when overriding get_queryset in Objecttypes Does this repo solve all the problems that are pointed out here? |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 3 replies
-
Hi, thanks for the question. I think you must be referring to this line:
As you can see here, I'm a bit confused what the part about Now, since the optimized database queries are run on the first ObjectType in the query, cached, and fetched from the cache on the child ObjectTypes, adding additional filtering will of course affect this, since we need to run an additional query to fetch the filtered amount of data. The I don't think there is any way around this currently. The optimizer only knows what to optimize based on the GraphQL schema, and uses standard queryset caching (i.e. If you'd like, you can make an issue about this, I'll get to implementing it in the near future. |
Beta Was this translation helpful? Give feedback.
-
Ok, I had a crack at this, and the initial idea I had didn't work, but I came up with a much cleaner one which doesn't need any additional queries. Essentially, you can now define a classmethod class ExampleType(DjangoObjectType):
@classmethod
def filter_queryset(cls, queryset: QuerySet, info: GQLInfo) -> QuerySet:
return queryset.filter(...) Released this in |
Beta Was this translation helpful? Give feedback.
-
i faced with an other problem class Menu(models.Model):
description = models.CharField(max_length=125, null=True, blank=True)
menu_name = models.CharField(max_length=125)
class SubMenu(models.Model):
description = models.CharField(max_length=125, null=True, blank=True)
menu = models.ForeignKey(
Menu,
on_delete=models.PROTECT,
related_name="sub_menus",
limit_choices_to={"is_active": True, "is_deleted": False},
null=True,
) when we want to write query like this to get submenu of each menu: query{
menuList{
edges{
node{
id
subMenus{
edges{
node{
name
}
}
}
}
}
}
} when we try to get submenus it's generate extra query for each item (it you check : https://docs.graphene-python.org/projects/django/en/latest/debug/ it will be more clear i think for you ) do you have any solution ? |
Beta Was this translation helpful? Give feedback.
-
here you're: class MenuType(DjangoObjectType):
class Meta:
model = Menu
interfaces = (CustomNode,)
filterset_class = MenuFilter
class SubMenuMainType(DjangoObjectType):
class Meta:
model = SubMenu
interfaces = (CustomNode,)
filterset_class = SubMenuFilter |
Beta Was this translation helpful? Give feedback.
Ok, I had a crack at this, and the initial idea I had didn't work, but I came up with a much cleaner one which doesn't need any additional queries.
Essentially, you can now define a classmethod
filter_queryset
on the ObjectType, which the optimizer will find and call when optimizing, whether the object type is the top level model, or a child prefetched model.Released this in
0.0.9