mirror of
https://github.com/graphql-python/graphene.git
synced 2025-02-02 12:44:15 +03:00
Add documentation to help specifying types for Unions
Also add an additional test case, update existing ones, to cover `resolve_type` and `Meta.possible_types` more
This commit is contained in:
parent
9c3e4bb7da
commit
2c92618648
|
@ -61,3 +61,63 @@ The above types have the following representation in a schema:
|
||||||
|
|
||||||
union SearchResult = Human | Droid | Starship
|
union SearchResult = Human | Droid | Starship
|
||||||
|
|
||||||
|
Resolving Types
|
||||||
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
When defining Unions, as with Interfaces, we need to tell the schema how to resolve the type of a returned object.
|
||||||
|
|
||||||
|
This can be achieved by:
|
||||||
|
|
||||||
|
- defining an `is_type_of`-method on each `ObjectType`
|
||||||
|
- defining the attribute `possible_types` on the Meta class
|
||||||
|
- defining a `resolve_type` on the Union
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
^^^^^^^^^
|
||||||
|
|
||||||
|
An example with `is_type_of` and `Meta.possible_types`:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
class one_object:
|
||||||
|
one = 'one'
|
||||||
|
|
||||||
|
class two_object:
|
||||||
|
two = 'two'
|
||||||
|
|
||||||
|
class One(ObjectType):
|
||||||
|
one = String()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def is_type_of(cls, root, info):
|
||||||
|
return isinstance(root, one_object)
|
||||||
|
|
||||||
|
class Two(ObjectType):
|
||||||
|
class Meta:
|
||||||
|
possible_types = (two_object,)
|
||||||
|
two = String()
|
||||||
|
|
||||||
|
class MyUnion(Union):
|
||||||
|
class Meta:
|
||||||
|
types = (One, Two)
|
||||||
|
|
||||||
|
|
||||||
|
An example with `resolve_type`:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
class One(ObjectType):
|
||||||
|
one = String()
|
||||||
|
|
||||||
|
class Two(ObjectType):
|
||||||
|
two = String()
|
||||||
|
|
||||||
|
class MyUnion(Union):
|
||||||
|
class Meta:
|
||||||
|
types = (One, Two)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def resolve_type(cls, instance, info)
|
||||||
|
if hasattr(instance, 'one'):
|
||||||
|
return One
|
||||||
|
else:
|
||||||
|
return Two
|
||||||
|
|
|
@ -65,12 +65,10 @@ def test_query_union():
|
||||||
return isinstance(root, one_object)
|
return isinstance(root, one_object)
|
||||||
|
|
||||||
class Two(ObjectType):
|
class Two(ObjectType):
|
||||||
|
class Meta:
|
||||||
|
possible_types = (two_object,)
|
||||||
two = String()
|
two = String()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_type_of(cls, root, info):
|
|
||||||
return isinstance(root, two_object)
|
|
||||||
|
|
||||||
class MyUnion(Union):
|
class MyUnion(Union):
|
||||||
class Meta:
|
class Meta:
|
||||||
types = (One, Two)
|
types = (One, Two)
|
||||||
|
@ -111,13 +109,10 @@ def test_query_interface():
|
||||||
class Two(ObjectType):
|
class Two(ObjectType):
|
||||||
class Meta:
|
class Meta:
|
||||||
interfaces = (MyInterface,)
|
interfaces = (MyInterface,)
|
||||||
|
possible_types = (two_object,)
|
||||||
|
|
||||||
two = String()
|
two = String()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def is_type_of(cls, root, info):
|
|
||||||
return isinstance(root, two_object)
|
|
||||||
|
|
||||||
class Query(ObjectType):
|
class Query(ObjectType):
|
||||||
interfaces = List(MyInterface)
|
interfaces = List(MyInterface)
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,16 @@ from ..field import Field
|
||||||
from ..objecttype import ObjectType
|
from ..objecttype import ObjectType
|
||||||
from ..union import Union
|
from ..union import Union
|
||||||
from ..unmountedtype import UnmountedType
|
from ..unmountedtype import UnmountedType
|
||||||
|
from ..schema import Schema
|
||||||
|
from ..scalars import String
|
||||||
|
|
||||||
|
|
||||||
class MyObjectType1(ObjectType):
|
class MyObjectType1(ObjectType):
|
||||||
pass
|
name = Field(String)
|
||||||
|
|
||||||
|
|
||||||
class MyObjectType2(ObjectType):
|
class MyObjectType2(ObjectType):
|
||||||
pass
|
not_name = Field(String)
|
||||||
|
|
||||||
|
|
||||||
def test_generate_union():
|
def test_generate_union():
|
||||||
|
@ -56,3 +58,38 @@ def test_union_can_be_mounted():
|
||||||
my_union_field = my_union_instance.mount_as(Field)
|
my_union_field = my_union_instance.mount_as(Field)
|
||||||
assert isinstance(my_union_field, Field)
|
assert isinstance(my_union_field, Field)
|
||||||
assert my_union_field.type == MyUnion
|
assert my_union_field.type == MyUnion
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_type_custom():
|
||||||
|
class MyUnion(Union):
|
||||||
|
class Meta:
|
||||||
|
types = (MyObjectType1, MyObjectType2)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def resolve_type(cls, instance, info):
|
||||||
|
if 'name' in instance:
|
||||||
|
return MyObjectType1
|
||||||
|
else:
|
||||||
|
return MyObjectType2
|
||||||
|
|
||||||
|
class Query(ObjectType):
|
||||||
|
test = Field(MyUnion)
|
||||||
|
|
||||||
|
def resolve_test(_, info):
|
||||||
|
return {'name': 'Type 1'}
|
||||||
|
|
||||||
|
schema = Schema(query=Query)
|
||||||
|
result = schema.execute(
|
||||||
|
"""
|
||||||
|
query {
|
||||||
|
test {
|
||||||
|
__typename
|
||||||
|
...on MyObjectType1 {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
assert not result.errors
|
||||||
|
assert result.data == {"test": {"__typename": "MyObjectType1", "name": "Type 1"}}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user