Как разрешить графен.Юнион Тип?
Я хочу создать UnionType(graphene.Union) из двух существующих типов (FirstType и SecondType) и быть в состоянии разрешить запрос этого типа объединения.
схема
class FirstType(DjangoObjectType):
class Meta:
model = FirstModel
class SecondType(DjangoObjectType):
class Meta:
model = SecondModel
class UnionType(graphene.Union):
class Meta:
types = (FirstType, SecondType)
Так что с этой схемой я хочу запросить все объекты из FirstType и SecondType с pk в некотором списке [pks]
query {
all_items(pks: [1,2,5,7]){
... on FirstType{
pk,
color,
}
... on SecondType{
pk,
size,
}
}
}
ПК из FirstType обычно не входят во SecondType.
Я попробовал как один ниже
def resolve_items(root, info, ids):
queryset1 = FirstModel.objects.filter(id__in=pks)
queryset2 = SecondModel.objects.filter(id__in=pks)
return queryset1 | queryset2
но выдает ошибку: "Невозможно объединить запросы в двух разных базовых моделях".
Я ожидаю следующий ответ от запроса:
{ 'data':
{'all_items':[
{'pk': 1,
'color': blue
},
{'pk': 2,
'size': 50.0
},
...
]}
}
Итак, как должен выглядеть распознаватель?
1 ответ
Документация по графену о типах объединения очень скудна. Вот рабочий пример того, как это правильно сделать:
from graphene import ObjectType, Field, List, String, Int, Union
mock_data = {
"episode": 3,
"characters": [
{
"type": "Droid",
"name": "R2-D2",
"primaryFunction": "Astromech"
},
{
"type": "Human",
"name": "Luke Skywalker",
"homePlanet": "Tatooine"
},
{
"type": "Starship",
"name": "Millennium Falcon",
"length": 35
}
]
}
class Human(ObjectType):
name = String()
homePlanet = String()
class Droid(ObjectType):
name = String()
primaryFunction = String()
class Starship(ObjectType):
name = String()
length = Int()
class Character(Union):
class Meta:
types = (Human, Droid, Starship)
@classmethod
def resolve_type(cls, instance, info):
if instance["type"] == "Human":
return Human
if instance["type"] == "Droid":
return Droid
if instance["type"] == "Starship":
return Starship
class RootQuery(ObjectType):
result = Field(SearchResult)
def resolve_result(_, info):
return mock_data
Затем для запроса типа
query Humans {
result {
episode
characters {
... on Droid {
name
}
... on Starship {
name
}
... on Human {
name
}
}
}
}
он возвращает правильный результат.
Итак, я был слишком сконцентрирован на объединении наборов запросов и не заметил, что могу просто вернуть список.
Итак, вот решение, которое дает мне ответ, который я ищу:
def resolve_items(root, info, ids):
items = []
queryset1 = FirstModel.objects.filter(id__in=pks)
items.extend(queryset1)
queryset2 = SecondModel.objects.filter(id__in=pks)
items.extend(queryset2)
return items