Python 如何隐藏/排除graphene_django wrt请求实体中外键的某些字段?
我已经阅读了关于如何在这些链接中排除(隐藏)django和graphene_django中的某些字段的内容:Python 如何隐藏/排除graphene_django wrt请求实体中外键的某些字段?,python,django,graphql,graphene-django,Python,Django,Graphql,Graphene Django,我已经阅读了关于如何在这些链接中排除(隐藏)django和graphene_django中的某些字段的内容: 等等 假设我们有下面的Post模型,它具有用户模型的外键 apps/posts/models.py 来自django.db导入模型的 从apps.users.models导入用户 班级职务(models.Model): author=models.ForeignKey( 用户, 在_delete=models.CASCADE上, 空=假 ) 已创建\u at=models.Dat
- 等等
Post
模型,它具有用户
模型的外键
apps/posts/models.py
来自django.db导入模型的
从apps.users.models导入用户
班级职务(models.Model):
author=models.ForeignKey(
用户,
在_delete=models.CASCADE上,
空=假
)
已创建\u at=models.DateTimeField(
auto\u now\u add=True,
)
title=models.TextField(
null=False,
最大长度=100,
)
content=models.TextField(
null=False,
)
定义(自我):
返回自己的标题
apps/users/models.py
来自django.db导入模型的
从django.contrib.auth.models导入AbstractUser
类用户(AbstractUser,models.Model):
电话号码=models.CharField(
空白=真,
空=真,
默认值=”,
最大长度=10,
详细名称=“电话号码”,
)
avatar=models.ImageField(
空=真,
上传_到class='static',
)
USERNAME\u FIELD=“USERNAME”
电子邮件\u FIELD=“电子邮件”
定义(自我):
返回self.username
我尝试了以下方法,但效果不理想:
apps/posts/schema.py
导入石墨烯
从graphene导入突变,InputObjectType,ObjectType
从graphene_django.types导入djangObjectType
从。模型导入后
类PostType(DjangObjectType):
类元:
型号=员额
排除_字段=[
“创建于”,成功了
“author.password”,我试图隐藏外键字段的方式
]
类查询(对象类型):
posts=石墨烯(
PostType
)
def解析_帖子(自我、信息):
#TODO:分页
return Post.objects.all()
屏幕截图:
如何在graphql模型类型中隐藏它的某些字段(如上例中的作者密码)?这仅用于在解析查询字段之前检查权限。(因此,不是对原始问题的回答) 像这样的东西会有用的
def permission_check_my_field(func):
@wraps(func)
def wrapper(self,info,**kwargs):
user=info.context.user
if (......) # permit condition here
return func(self, info,**kwargs)
else:
return None
return wrapper
class Query(graphene.ObjectType):
my_field = graphene.Field(...) # or graphene.List or .....
@permission_check_my_field
def resolve_my_field(......)
# do your normal work
更新
如果用户数据足以检查字段是否可访问(如)。但是,如果需要检查用户是否已被授予访问该字段的某些权限,则需要执行以下操作:
def permission_check_in_query(perm):
def wrapped_decorator(func):
@wraps(func)
def wrapper(self,info,**kwargs):
user=info.context.user
if user.has_perm(perm) # check if the user has privilege
return func(self, info,**kwargs)
else:
return None
# All fields are not nullable, so `return None' might throw error. You can pass `what you need to return` in decorator argument and use it here , to avoid this.
return wrapper
return wrapped_decorator
class Query(graphene.ObjectType):
my_field = graphene.Field(...) # or graphene.List or .....
@permission_check_in_query('model.access_my_field') # your permission code
# learn django permissions if you are not sure what it is
# doesn't have to be django_permission, can be any argument like 'is_it_a_superuser' that you will use to check user privilege. Modify decorator code accordingly
def resolve_my_field(......)
# do your normal work
这样,您就可以对任何字段和任何权限进行重用。只需将decorator@permission\u check\u in\u query(您的参数)
添加到任何需要在解析之前进行权限检查的字段上方
TLDR:这个答案与API接受和返回的数据类型类似。它只提供可重用性和权限检查。从评论中,我了解到您有一个
用户类型
类
您可以使用meta as中的排除选项
class UserType(DjangoObjectType):
class Meta:
model = User
exclude = ('password',)
类用户类型(DjangObjectType):
类元:
模型=用户
排除=('password',)
更新
您还可以使用自定义解析器检查请求的实体
class UserType(DjangoObjectType):
password = graphene.String()
def resolve_password(self, info):
requested_user = info.context.user
if requested_user.email in ['admin@test.com', 'ceo@test.com']:
return self.password
return None
class Meta:
model = User
fields = '__all__'
类用户类型(DjangObjectType):
密码=graphene.String()
def解析_密码(自我、信息):
请求的用户=info.context.user
如有要求,请在['admin@test.com', 'ceo@test.com']:
返回自我密码
一无所获
类元:
模型=用户
fields='\uuuu all\uuuuu'
如何创建一个AuthorType(djangObjectType)
来排除字段password
,并在PostType
中使用该类型和author=graphene.field(AuthorType)
@SagarAdhikari您的意思是将其添加到PostType元类中吗?不,元类上方,(类似于类变量)@SagarAdhikari你能给我举个例子吗?想象一下您基于不同权限执行此操作的情况。例如,超级用户可以看到电子邮件字段,但普通用户看不到。GraphQL API需要事先指定可以从服务器获取/发布的数据类型。所以,据我所知,这是违反graphql标准的。但是,您可以检查权限,并向普通用户发送消息“此字段不可访问”,而不是发送数据。我已经为这个问题添加了奖励,如果您能指导我怎么做并更新您的答案,我将不胜感激。我给出的这个答案与其他答案类似,除了返回“PermissionDenied”之外,我刚刚添加了decorators以实现可重用性。您可以创建一个接受参数的decorator,即您的权限代码(这里我使用了无参数decorator),这将使其可用于任何字段。现在,我用参数更新了docorator,您可以在其中传递权限和检查。现在一切正常:)我不想为所有用户排除它。正如我在帖子中解释的,我想对具有不同权限的特定用户隐藏它。哦。。我懂了。好了,没有现成的方法来进行这种权限检查。你是说它有严重的安全问题?如果你能告诉我,我将不胜感激。我不认为这是一个安全问题。我认为这是“这个功能还没有在graphene中实现”,那么Facebook、Instagram和其他人是如何使用它的呢?你是说他们为此尝试了不同的API?比如restful api?