Вот подход, который я бы выбрал, основываясь на комментариях. Основной проблемой здесь является возможность получить список полей, запрошенных запросом в распознавателе. Для этого я использую код, адаптированный с здесь :
def get_requested_fields(info):
"""Get list of fields requested in a query."""
fragments = info.fragments
def iterate_field_names(prefix, field):
name = field.name.value
if isinstance(field, FragmentSpread):
results = []
new_prefix = prefix
sub_selection = fragments[name].selection_set.selections
else:
results = [prefix + name]
new_prefix = prefix + name + '.'
sub_selection = \
field.selection_set.selections if field.selection_set else []
for sub_field in sub_selection:
results += iterate_field_names(new_prefix, sub_field)
return results
results = iterate_field_names('', info.field_asts[0])
return results
Остальное должно быть достаточно простым:
import graphene
from django.contrib.auth import get_user_model
from graphene_django import DjangoObjectType
class AuthorizationError(Exception):
"""Authorization failed."""
class UserType(DjangoObjectType):
class Meta:
model = get_user_model()
fields = ("id", "username", "email")
class Query(object):
user = graphene.Field(UserType, user_id=graphene.Int())
def resolve_user(self, info, user_id):
user = get_user_model().objects.get(pk=user_id)
if info.context.user.id != user_id:
fields = get_requested_fields(info)
if 'user.email' in fields:
raise AuthorizationError('Not authorized to access user email')
return user