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
|
||||
|
||||
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)
|
||||
|
||||
class Two(ObjectType):
|
||||
class Meta:
|
||||
possible_types = (two_object,)
|
||||
two = String()
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, root, info):
|
||||
return isinstance(root, two_object)
|
||||
|
||||
class MyUnion(Union):
|
||||
class Meta:
|
||||
types = (One, Two)
|
||||
|
@ -111,13 +109,10 @@ def test_query_interface():
|
|||
class Two(ObjectType):
|
||||
class Meta:
|
||||
interfaces = (MyInterface,)
|
||||
possible_types = (two_object,)
|
||||
|
||||
two = String()
|
||||
|
||||
@classmethod
|
||||
def is_type_of(cls, root, info):
|
||||
return isinstance(root, two_object)
|
||||
|
||||
class Query(ObjectType):
|
||||
interfaces = List(MyInterface)
|
||||
|
||||
|
|
|
@ -4,14 +4,16 @@ from ..field import Field
|
|||
from ..objecttype import ObjectType
|
||||
from ..union import Union
|
||||
from ..unmountedtype import UnmountedType
|
||||
from ..schema import Schema
|
||||
from ..scalars import String
|
||||
|
||||
|
||||
class MyObjectType1(ObjectType):
|
||||
pass
|
||||
name = Field(String)
|
||||
|
||||
|
||||
class MyObjectType2(ObjectType):
|
||||
pass
|
||||
not_name = Field(String)
|
||||
|
||||
|
||||
def test_generate_union():
|
||||
|
@ -56,3 +58,38 @@ def test_union_can_be_mounted():
|
|||
my_union_field = my_union_instance.mount_as(Field)
|
||||
assert isinstance(my_union_field, Field)
|
||||
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