# profiles/schema.py
import graphene
from graphene_django.types import DjangoObjectType
from .models import (ProfileOrganization, ProfilePlace, ProfileTeam, ProfileUser,ProfileURL, Sport)
# [ START: Types ]
class SportType(DjangoObjectType):
class Meta:
model = Sport
class ProfileURLType(DjangoObjectType):
class Meta:
model = ProfileURL
slug = graphene.String()
model_name = graphene.String()
def resolve_slug(self, info):
return self.slug
def resolve_model_name(self, info):
return self.content_object.__class__.__name__ # ex. 'ProfileTeam'
class ProfileOrganizationType(DjangoObjectType):
"""
Use this class as a basic class for other Profile Types classes
"""
class Meta:
model = ProfileOrganization
fields = ('name', 'logo_data', 'profile_url')
profile_url = graphene.Field(ProfileURLType)
def resolve_profile_url(self, args):
return self.profile_url.first()
class ProfilePlaceType(ProfileOrganizationType):
class Meta:
model = ProfilePlace
class ProfileTeamType(ProfileOrganizationType):
class Meta:
model = ProfileTeam
class ProfileUserType(ProfileOrganizationType):
class Meta:
model = ProfileUser
class ProfileTypeUnion(graphene.Union):
class Meta:
types = (ProfileOrganizationType, ProfileTeamType, ProfilePlaceType, ProfileUserType)
# [ END: Types ]
# [ START: Queries ]
class Query(graphene.ObjectType):
"""
EXAMPLE OF QUERY:
query profileDetails {
profileDetails(profileUrl: "8auB-pMH-6Sh") {
... on ProfileTeamType {
id,
name,
skillLevel,
sport {
name
},
profileUrl {
slug,
modelName
}
}
... on ProfilePlaceType {
id,
name,
sports {
name
},
profileUrl {
slug,
modelName
}
}
}
}
"""
profile_details = graphene.Field(ProfileTypeUnion, required=True, profile_url=graphene.String())
def resolve_profile_details(self, info, profile_url):
profile_url_type = ContentType.objects.get(app_label='profiles', model='profileurl')
profile_url_inst = profile_url_type.get_object_for_this_type(slug=profile_url)
return profile_url_inst.content_object
# [ END: Queries ]
... on ProfileTeamType
是内联片段(详细信息)。如您所见,我们在上面的示例中查询了 2 个片段(但是在我的情况下,根据配置文件类型的数量,它应该是 4 个),但是只有一个片段/模型返回数据 - 引用profileUrl
了询问。
从前端根据收到的信息,modelName
我们可以根据需要处理字段。
此外,上面提到的片段 > 1 的查询会在浏览器的控制台中引发 2 个错误(我在前端使用 Apollo 客户端):
您正在使用简单(启发式)片段匹配器,但您的查询包含联合或接口类型。Apollo Client 将无法准确映射片段。要消除此错误,请
IntrospectionFragmentMatcher
按照文档中的说明使用:
https ://www.apollographql.com/docs/react/advanced/fragments.html#fragment-matcher
(错误链接不正确。正确的是这个。)
警告:启发式片段匹配正在进行!
看来这是一个错误(github问题)。
为了修复它,我们需要在 Apollo 设置中添加缓存选项,它应该如下所示:
import ApolloClient from 'apollo-client';
import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'
import { HttpLink } from 'apollo-link-http';
const fragmentMatcher = new IntrospectionFragmentMatcher({
introspectionQueryResultData: {
__schema: {
types: []
}
}
})
const cache = new InMemoryCache({ fragmentMatcher });
const client = new ApolloClient({
cache,
link: new HttpLink(),
});