mirror of
				https://github.com/graphql-python/graphene-django.git
				synced 2025-11-04 09:57:53 +03:00 
			
		
		
		
	Improve DjangoListField (#929)
This commit is contained in:
		
							parent
							
								
									8990e173ac
								
							
						
					
					
						commit
						b4e34a5794
					
				
							
								
								
									
										83
									
								
								docs/fields.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								docs/fields.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,83 @@
 | 
				
			||||||
 | 
					Fields
 | 
				
			||||||
 | 
					======
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Graphene-Django provides some useful fields to help integrate Django with your GraphQL
 | 
				
			||||||
 | 
					Schema.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DjangoListField
 | 
				
			||||||
 | 
					---------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					``DjangoListField`` allows you to define a list of :ref:`DjangoObjectType<queries-objecttypes>`'s. By default it will resolve the default queryset of the Django model.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   from graphene import ObjectType, Schema
 | 
				
			||||||
 | 
					   from graphene_django import DjangoListField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   class RecipeType(DjangoObjectType):
 | 
				
			||||||
 | 
					      class Meta:
 | 
				
			||||||
 | 
					         model = Recipe
 | 
				
			||||||
 | 
					         fields = ("title", "instructions")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   class Query(ObjectType):
 | 
				
			||||||
 | 
					      recipes = DjangoListField(RecipeType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   schema = Schema(query=Query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above code results in the following schema definition:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   schema {
 | 
				
			||||||
 | 
					     query: Query
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   type Query {
 | 
				
			||||||
 | 
					     recipes: [RecipeType!]
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   type RecipeType {
 | 
				
			||||||
 | 
					     title: String!
 | 
				
			||||||
 | 
					     instructions: String!
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Custom resolvers
 | 
				
			||||||
 | 
					****************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If your ``DjangoObjectType`` has defined a custom
 | 
				
			||||||
 | 
					:ref:`get_queryset<django-objecttype-get-queryset>` method, when resolving a
 | 
				
			||||||
 | 
					``DjangoListField`` it will be called with either the return of the field
 | 
				
			||||||
 | 
					resolver (if one is defined) or the default queryeset from the Django model.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example the following schema will only resolve recipes which have been
 | 
				
			||||||
 | 
					published and have a title:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   from graphene import ObjectType, Schema
 | 
				
			||||||
 | 
					   from graphene_django import DjangoListField
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   class RecipeType(DjangoObjectType):
 | 
				
			||||||
 | 
					      class Meta:
 | 
				
			||||||
 | 
					         model = Recipe
 | 
				
			||||||
 | 
					         fields = ("title", "instructions")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @classmethod
 | 
				
			||||||
 | 
					      def get_queryset(cls, queryset, info):
 | 
				
			||||||
 | 
					         # Filter out recipes that have no title
 | 
				
			||||||
 | 
					         return queryset.exclude(title__exact="")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   class Query(ObjectType):
 | 
				
			||||||
 | 
					      recipes = DjangoListField(RecipeType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      def resolve_recipes(parent, info):
 | 
				
			||||||
 | 
					         # Only get recipes that have been published
 | 
				
			||||||
 | 
					         return Recipe.objects.filter(published=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   schema = Schema(query=Query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DjangoConnectionField
 | 
				
			||||||
 | 
					---------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*TODO*
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
Filtering
 | 
					Filtering
 | 
				
			||||||
=========
 | 
					=========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Graphene integrates with
 | 
					Graphene-Django integrates with
 | 
				
			||||||
`django-filter <https://django-filter.readthedocs.io/en/master/>`__ (2.x for
 | 
					`django-filter <https://django-filter.readthedocs.io/en/master/>`__ (2.x for
 | 
				
			||||||
Python 3 or 1.x for Python 2) to provide filtering of results. See the `usage
 | 
					Python 3 or 1.x for Python 2) to provide filtering of results. See the `usage
 | 
				
			||||||
documentation <https://django-filter.readthedocs.io/en/master/guide/usage.html#the-filter>`__
 | 
					documentation <https://django-filter.readthedocs.io/en/master/guide/usage.html#the-filter>`__
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@ For more advanced use, check out the Relay tutorial.
 | 
				
			||||||
   tutorial-relay
 | 
					   tutorial-relay
 | 
				
			||||||
   schema
 | 
					   schema
 | 
				
			||||||
   queries
 | 
					   queries
 | 
				
			||||||
 | 
					   fields
 | 
				
			||||||
   extra-types
 | 
					   extra-types
 | 
				
			||||||
   mutations
 | 
					   mutations
 | 
				
			||||||
   filtering
 | 
					   filtering
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,5 @@
 | 
				
			||||||
 | 
					.. _queries-objecttypes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Queries & ObjectTypes
 | 
					Queries & ObjectTypes
 | 
				
			||||||
=====================
 | 
					=====================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -205,6 +207,8 @@ need to create the most basic class for this to work:
 | 
				
			||||||
        class Meta:
 | 
					        class Meta:
 | 
				
			||||||
            model = Category
 | 
					            model = Category
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _django-objecttype-get-queryset:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Default QuerySet
 | 
					Default QuerySet
 | 
				
			||||||
-----------------
 | 
					-----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,11 @@
 | 
				
			||||||
 | 
					from .fields import DjangoConnectionField, DjangoListField
 | 
				
			||||||
from .types import DjangoObjectType
 | 
					from .types import DjangoObjectType
 | 
				
			||||||
from .fields import DjangoConnectionField
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
__version__ = "2.9.1"
 | 
					__version__ = "2.9.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = ["__version__", "DjangoObjectType", "DjangoConnectionField"]
 | 
					__all__ = [
 | 
				
			||||||
 | 
					    "__version__",
 | 
				
			||||||
 | 
					    "DjangoObjectType",
 | 
				
			||||||
 | 
					    "DjangoListField",
 | 
				
			||||||
 | 
					    "DjangoConnectionField",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,16 +38,21 @@ class DjangoListField(Field):
 | 
				
			||||||
    def model(self):
 | 
					    def model(self):
 | 
				
			||||||
        return self._underlying_type._meta.model
 | 
					        return self._underlying_type._meta.model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_default_queryset(self):
 | 
				
			||||||
 | 
					        return self.model._default_manager.get_queryset()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def list_resolver(django_object_type, resolver, root, info, **args):
 | 
					    def list_resolver(
 | 
				
			||||||
 | 
					        django_object_type, resolver, default_queryset, root, info, **args
 | 
				
			||||||
 | 
					    ):
 | 
				
			||||||
        queryset = maybe_queryset(resolver(root, info, **args))
 | 
					        queryset = maybe_queryset(resolver(root, info, **args))
 | 
				
			||||||
        if queryset is None:
 | 
					        if queryset is None:
 | 
				
			||||||
            # Default to Django Model queryset
 | 
					            queryset = default_queryset
 | 
				
			||||||
            # N.B. This happens if DjangoListField is used in the top level Query object
 | 
					
 | 
				
			||||||
            model_manager = django_object_type._meta.model.objects
 | 
					        if isinstance(queryset, QuerySet):
 | 
				
			||||||
            queryset = maybe_queryset(
 | 
					            # Pass queryset to the DjangoObjectType get_queryset method
 | 
				
			||||||
                django_object_type.get_queryset(model_manager, info)
 | 
					            queryset = maybe_queryset(django_object_type.get_queryset(queryset, info))
 | 
				
			||||||
            )
 | 
					
 | 
				
			||||||
        return queryset
 | 
					        return queryset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_resolver(self, parent_resolver):
 | 
					    def get_resolver(self, parent_resolver):
 | 
				
			||||||
| 
						 | 
					@ -55,7 +60,12 @@ class DjangoListField(Field):
 | 
				
			||||||
        if isinstance(_type, NonNull):
 | 
					        if isinstance(_type, NonNull):
 | 
				
			||||||
            _type = _type.of_type
 | 
					            _type = _type.of_type
 | 
				
			||||||
        django_object_type = _type.of_type.of_type
 | 
					        django_object_type = _type.of_type.of_type
 | 
				
			||||||
        return partial(self.list_resolver, django_object_type, parent_resolver)
 | 
					        return partial(
 | 
				
			||||||
 | 
					            self.list_resolver,
 | 
				
			||||||
 | 
					            django_object_type,
 | 
				
			||||||
 | 
					            parent_resolver,
 | 
				
			||||||
 | 
					            self.get_default_queryset(),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoConnectionField(ConnectionField):
 | 
					class DjangoConnectionField(ConnectionField):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
 | 
					from django.db.models import Count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -141,13 +142,26 @@ class TestDjangoListField:
 | 
				
			||||||
            pub_date_time=datetime.datetime.now(),
 | 
					            pub_date_time=datetime.datetime.now(),
 | 
				
			||||||
            editor=r1,
 | 
					            editor=r1,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					        ArticleModel.objects.create(
 | 
				
			||||||
 | 
					            headline="Not so good news",
 | 
				
			||||||
 | 
					            reporter=r1,
 | 
				
			||||||
 | 
					            pub_date=datetime.date.today(),
 | 
				
			||||||
 | 
					            pub_date_time=datetime.datetime.now(),
 | 
				
			||||||
 | 
					            editor=r1,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = schema.execute(query)
 | 
					        result = schema.execute(query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert not result.errors
 | 
					        assert not result.errors
 | 
				
			||||||
        assert result.data == {
 | 
					        assert result.data == {
 | 
				
			||||||
            "reporters": [
 | 
					            "reporters": [
 | 
				
			||||||
                {"firstName": "Tara", "articles": [{"headline": "Amazing news"}]},
 | 
					                {
 | 
				
			||||||
 | 
					                    "firstName": "Tara",
 | 
				
			||||||
 | 
					                    "articles": [
 | 
				
			||||||
 | 
					                        {"headline": "Amazing news"},
 | 
				
			||||||
 | 
					                        {"headline": "Not so good news"},
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
                {"firstName": "Debra", "articles": []},
 | 
					                {"firstName": "Debra", "articles": []},
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -163,8 +177,8 @@ class TestDjangoListField:
 | 
				
			||||||
                model = ReporterModel
 | 
					                model = ReporterModel
 | 
				
			||||||
                fields = ("first_name", "articles")
 | 
					                fields = ("first_name", "articles")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            def resolve_reporters(reporter, info):
 | 
					            def resolve_articles(reporter, info):
 | 
				
			||||||
                return reporter.articles.all()
 | 
					                return reporter.articles.filter(headline__contains="Amazing")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        class Query(ObjectType):
 | 
					        class Query(ObjectType):
 | 
				
			||||||
            reporters = DjangoListField(Reporter)
 | 
					            reporters = DjangoListField(Reporter)
 | 
				
			||||||
| 
						 | 
					@ -192,6 +206,13 @@ class TestDjangoListField:
 | 
				
			||||||
            pub_date_time=datetime.datetime.now(),
 | 
					            pub_date_time=datetime.datetime.now(),
 | 
				
			||||||
            editor=r1,
 | 
					            editor=r1,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					        ArticleModel.objects.create(
 | 
				
			||||||
 | 
					            headline="Not so good news",
 | 
				
			||||||
 | 
					            reporter=r1,
 | 
				
			||||||
 | 
					            pub_date=datetime.date.today(),
 | 
				
			||||||
 | 
					            pub_date_time=datetime.datetime.now(),
 | 
				
			||||||
 | 
					            editor=r1,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = schema.execute(query)
 | 
					        result = schema.execute(query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -202,3 +223,155 @@ class TestDjangoListField:
 | 
				
			||||||
                {"firstName": "Debra", "articles": []},
 | 
					                {"firstName": "Debra", "articles": []},
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_get_queryset_filter(self):
 | 
				
			||||||
 | 
					        class Reporter(DjangoObjectType):
 | 
				
			||||||
 | 
					            class Meta:
 | 
				
			||||||
 | 
					                model = ReporterModel
 | 
				
			||||||
 | 
					                fields = ("first_name", "articles")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @classmethod
 | 
				
			||||||
 | 
					            def get_queryset(cls, queryset, info):
 | 
				
			||||||
 | 
					                # Only get reporters with at least 1 article
 | 
				
			||||||
 | 
					                return queryset.annotate(article_count=Count("articles")).filter(
 | 
				
			||||||
 | 
					                    article_count__gt=0
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Query(ObjectType):
 | 
				
			||||||
 | 
					            reporters = DjangoListField(Reporter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def resolve_reporters(_, info):
 | 
				
			||||||
 | 
					                return ReporterModel.objects.all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        schema = Schema(query=Query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        query = """
 | 
				
			||||||
 | 
					            query {
 | 
				
			||||||
 | 
					                reporters {
 | 
				
			||||||
 | 
					                    firstName
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        r1 = ReporterModel.objects.create(first_name="Tara", last_name="West")
 | 
				
			||||||
 | 
					        ReporterModel.objects.create(first_name="Debra", last_name="Payne")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ArticleModel.objects.create(
 | 
				
			||||||
 | 
					            headline="Amazing news",
 | 
				
			||||||
 | 
					            reporter=r1,
 | 
				
			||||||
 | 
					            pub_date=datetime.date.today(),
 | 
				
			||||||
 | 
					            pub_date_time=datetime.datetime.now(),
 | 
				
			||||||
 | 
					            editor=r1,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        result = schema.execute(query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert not result.errors
 | 
				
			||||||
 | 
					        assert result.data == {"reporters": [{"firstName": "Tara"},]}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_resolve_list(self):
 | 
				
			||||||
 | 
					        """Resolving a plain list should work (and not call get_queryset)"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Reporter(DjangoObjectType):
 | 
				
			||||||
 | 
					            class Meta:
 | 
				
			||||||
 | 
					                model = ReporterModel
 | 
				
			||||||
 | 
					                fields = ("first_name", "articles")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @classmethod
 | 
				
			||||||
 | 
					            def get_queryset(cls, queryset, info):
 | 
				
			||||||
 | 
					                # Only get reporters with at least 1 article
 | 
				
			||||||
 | 
					                return queryset.annotate(article_count=Count("articles")).filter(
 | 
				
			||||||
 | 
					                    article_count__gt=0
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Query(ObjectType):
 | 
				
			||||||
 | 
					            reporters = DjangoListField(Reporter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def resolve_reporters(_, info):
 | 
				
			||||||
 | 
					                return [ReporterModel.objects.get(first_name="Debra")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        schema = Schema(query=Query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        query = """
 | 
				
			||||||
 | 
					            query {
 | 
				
			||||||
 | 
					                reporters {
 | 
				
			||||||
 | 
					                    firstName
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        r1 = ReporterModel.objects.create(first_name="Tara", last_name="West")
 | 
				
			||||||
 | 
					        ReporterModel.objects.create(first_name="Debra", last_name="Payne")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ArticleModel.objects.create(
 | 
				
			||||||
 | 
					            headline="Amazing news",
 | 
				
			||||||
 | 
					            reporter=r1,
 | 
				
			||||||
 | 
					            pub_date=datetime.date.today(),
 | 
				
			||||||
 | 
					            pub_date_time=datetime.datetime.now(),
 | 
				
			||||||
 | 
					            editor=r1,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        result = schema.execute(query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert not result.errors
 | 
				
			||||||
 | 
					        assert result.data == {"reporters": [{"firstName": "Debra"},]}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_get_queryset_foreign_key(self):
 | 
				
			||||||
 | 
					        class Article(DjangoObjectType):
 | 
				
			||||||
 | 
					            class Meta:
 | 
				
			||||||
 | 
					                model = ArticleModel
 | 
				
			||||||
 | 
					                fields = ("headline",)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            @classmethod
 | 
				
			||||||
 | 
					            def get_queryset(cls, queryset, info):
 | 
				
			||||||
 | 
					                # Rose tinted glasses
 | 
				
			||||||
 | 
					                return queryset.exclude(headline__contains="Not so good")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Reporter(DjangoObjectType):
 | 
				
			||||||
 | 
					            class Meta:
 | 
				
			||||||
 | 
					                model = ReporterModel
 | 
				
			||||||
 | 
					                fields = ("first_name", "articles")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        class Query(ObjectType):
 | 
				
			||||||
 | 
					            reporters = DjangoListField(Reporter)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        schema = Schema(query=Query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        query = """
 | 
				
			||||||
 | 
					            query {
 | 
				
			||||||
 | 
					                reporters {
 | 
				
			||||||
 | 
					                    firstName
 | 
				
			||||||
 | 
					                    articles {
 | 
				
			||||||
 | 
					                        headline
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        r1 = ReporterModel.objects.create(first_name="Tara", last_name="West")
 | 
				
			||||||
 | 
					        ReporterModel.objects.create(first_name="Debra", last_name="Payne")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ArticleModel.objects.create(
 | 
				
			||||||
 | 
					            headline="Amazing news",
 | 
				
			||||||
 | 
					            reporter=r1,
 | 
				
			||||||
 | 
					            pub_date=datetime.date.today(),
 | 
				
			||||||
 | 
					            pub_date_time=datetime.datetime.now(),
 | 
				
			||||||
 | 
					            editor=r1,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        ArticleModel.objects.create(
 | 
				
			||||||
 | 
					            headline="Not so good news",
 | 
				
			||||||
 | 
					            reporter=r1,
 | 
				
			||||||
 | 
					            pub_date=datetime.date.today(),
 | 
				
			||||||
 | 
					            pub_date_time=datetime.datetime.now(),
 | 
				
			||||||
 | 
					            editor=r1,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        result = schema.execute(query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert not result.errors
 | 
				
			||||||
 | 
					        assert result.data == {
 | 
				
			||||||
 | 
					            "reporters": [
 | 
				
			||||||
 | 
					                {"firstName": "Tara", "articles": [{"headline": "Amazing news"},],},
 | 
				
			||||||
 | 
					                {"firstName": "Debra", "articles": []},
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user