Mos*_*imi 5 python django graphql graphene-django
我已阅读有关如何在这些链接中排除(隐藏)django 和 graphene_django 中的某些字段的信息:
想象一下,我们有以下Post模型,它具有模型的外键User。
应用程序/帖子/models.py
from django.db import models
from apps.users.models import User
class Post(models.Model):
author = models.ForeignKey(
User,
on_delete=models.CASCADE,
null=False
)
created_at = models.DateTimeField(
auto_now_add=True,
)
title = models.TextField(
null=False,
max_length=100,
)
content = models.TextField(
null=False,
)
def __str__(self):
return self.title
Run Code Online (Sandbox Code Playgroud)
应用程序/用户/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser, models.Model):
phone_no = models.CharField(
blank=True,
null=True,
default="",
max_length=10,
verbose_name="Phone Number",
)
avatar = models.ImageField(
null=True,
upload_to='static',
)
USERNAME_FIELD = "username"
EMAIL_FIELD = "email"
def __str__(self):
return self.username
Run Code Online (Sandbox Code Playgroud)
我尝试了以下操作,但没有按预期工作:
应用程序/帖子/schema.py
import graphene
from graphene import Mutation, InputObjectType, ObjectType
from graphene_django.types import DjangoObjectType
from .models import Post
class PostType(DjangoObjectType):
class Meta:
model = Post
exclude_fields = [
'created_at', #it worked
'author.password', #the way I tried to hide the foreign key field
]
class Query(ObjectType):
posts = graphene.List(
PostType
)
def resolve_posts(self, info):
#TODO: pagination
return Post.objects.all()
Run Code Online (Sandbox Code Playgroud)
截屏:
如何在 graphql 模型类型中隐藏它的某些字段(如上例中的作者密码)?
从评论中我了解到你有一个UserType班级
exclude您可以在元中使用该选项,
class UserType(DjangoObjectType):
class Meta:
model = User
exclude = ('password',)Run Code Online (Sandbox Code Playgroud)
您还可以使用自定义解析器来检查请求的实体
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__'Run Code Online (Sandbox Code Playgroud)
这只是在解析查询字段之前检查权限的答案。(所以,不是原始问题的答案)
像这样的东西会起作用。
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
Run Code Online (Sandbox Code Playgroud)
更新。
如果用户数据足以检查该字段是否可访问(如其他答案),则上述代码有效。但是,如果您需要检查用户是否已被授予访问该字段的某些权限,那么您需要这样做:
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
Run Code Online (Sandbox Code Playgroud)
这样做,您可以重用任何字段和任何权限。@permission_check_in_query(your arguments)只需在解析之前需要进行权限检查的任何字段上方添加装饰器即可。
TLDR:这个答案与有关 API 接受和返回的数据类型的其他答案类似。它只是提供可重用性和权限检查。
| 归档时间: |
|
| 查看次数: |
1220 次 |
| 最近记录: |