From a05e4b32c30cfe1ace1df44a3275cbaadfd5331f Mon Sep 17 00:00:00 2001 From: Darrel O'Pry Date: Tue, 9 Aug 2022 04:55:01 -0400 Subject: [PATCH] Support comma separated list of content types for the content_type filter on pages query (#250) --- docs/general-usage/graphql-types.rst | 2 +- example/example/tests/test_grapple.py | 10 ++++++++++ grapple/types/pages.py | 19 +++++++++++++------ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/docs/general-usage/graphql-types.rst b/docs/general-usage/graphql-types.rst index 558af09c..5da43127 100644 --- a/docs/general-usage/graphql-types.rst +++ b/docs/general-usage/graphql-types.rst @@ -70,7 +70,7 @@ accepts the following arguments: offset: PositiveInt order: String searchQuery: String - contentType: String + contentType: String # comma separated list of content types in app.Model notation inSite: Boolean diff --git a/example/example/tests/test_grapple.py b/example/example/tests/test_grapple.py index afd9679a..30376d63 100644 --- a/example/example/tests/test_grapple.py +++ b/example/example/tests/test_grapple.py @@ -156,6 +156,16 @@ def test_pages_content_type_filter(self): [int(p["id"]) for p in data], [self.blog_post.id, another_post.id] ) + results = self.client.execute( + query, variables={"content_type": "home.HomePage,home.BlogPage"} + ) + data = results["data"]["pages"] + self.assertEquals(len(data), 3) + self.assertListEqual( + [int(p["id"]) for p in data], + [self.home.id, self.blog_post.id, another_post.id], + ) + results = self.client.execute( query, variables={"content_type": "bogus.ContentType"} ) diff --git a/grapple/types/pages.py b/grapple/types/pages.py index 020164d7..470e6da7 100644 --- a/grapple/types/pages.py +++ b/grapple/types/pages.py @@ -1,5 +1,6 @@ import graphene from django.contrib.contenttypes.models import ContentType +from django.db.models import Q from django.dispatch import receiver from django.utils.translation import gettext_lazy as _ from graphene_django.types import DjangoObjectType @@ -233,7 +234,9 @@ class Mixin: graphene.NonNull(lambda: PageInterface), content_type=graphene.Argument( graphene.String, - description=_("Filter by content type. Uses the `app.Model` notation."), + description=_( + "Filter by content type. Uses the `app.Model` notation. Accepts a comma separated list of content types." + ), ), in_site=graphene.Argument( graphene.Boolean, @@ -284,11 +287,15 @@ def resolve_pages(self, info, **kwargs): pages = pages.in_site(site) content_type = kwargs.pop("content_type", None) - if content_type: - app_label, model = content_type.strip().lower().split(".") - pages = pages.filter( - content_type__app_label=app_label, content_type__model=model - ) + content_types = content_type.split(",") if content_type else None + if content_types: + filters = Q() + for content_type in content_types: + app_label, model = content_type.strip().lower().split(".") + filters |= Q( + content_type__app_label=app_label, content_type__model=model + ) + pages = pages.filter(filters) return resolve_queryset(pages, info, **kwargs)