[英]How to show specific field only to the user profile owner in graphene-django?
我的graphene-django
應用程序中有以下模式:
import graphene
from django.contrib.auth import get_user_model
from graphene_django import DjangoObjectType
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:
# If the query didn't access email field -> query is ok
# If the query tried to access email field -> raise an error
else:
# Logged in as the user we're querying -> let the query access all the fields
我希望能夠通過以下方式查詢架構:
# Logged in as user 1 => no errors, because we're allowed to see all fields
query {
user (userId: 1) {
id
username
email
}
}
# Not logged in as user 1 => no errors, because not trying to see email
query {
user (userId: 1) {
id
username
}
}
# Not logged in as user 1 => return error because accessing email
query {
user (userId: 1) {
id
username
email
}
}
我怎樣才能做到只有登錄用戶才能看到自己個人資料的email
字段,而其他人不能看到其他人的電子郵件?
這是我根據評論采取的方法。 這里的主要問題是能夠獲得解析器中查詢請求的字段列表。 為此,我使用了改編自此處的代碼:
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
rest 應該非常簡單:
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
我最終只是這樣做了,其中查詢自己的信息時返回email
的實際值,而其他人則返回None
:
import graphene
from django.contrib.auth import get_user_model
from graphene_django import DjangoObjectType
class UserType(DjangoObjectType):
class Meta:
model = get_user_model()
fields = ("id", "username", "email")
def resolve_email(self, info):
if info.context.user.is_authenticated and self.pk == info.context.user.pk:
return self.email
else:
return None
class Query(graphene.ObjectType):
user = graphene.Field(UserType, user_id=graphene.Int())
def resolve_user(self, info, user_id):
return get_user_model().objects.get(pk=user_id)
當前的答案太復雜了。 只需創建兩個 ObjectType,例如:
class PublicUserType(DjangoObjectType):
class Meta:
model = get_user_model()
fields = ('id', 'username')
class PrivateUserType(DjangoObjectType):
class Meta:
model = get_user_model()
花了 4 個多小時嘗試其他解決方案才意識到原來如此簡單
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.