首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在graphene-django中仅向用户配置文件所有者显示特定字段?

如何在graphene-django中仅向用户配置文件所有者显示特定字段?
EN

Stack Overflow用户
提问于 2019-10-10 20:12:23
回答 3查看 1.1K关注 0票数 3

我的graphene-django应用程序中有以下模式:

代码语言:javascript
复制
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

我希望能够通过以下方式查询架构:

代码语言:javascript
复制
# 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字段,而其他人则无法看到其他人的电子邮件?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-07 05:58:34

我最终这样做了,当查询自己的信息时,返回email的实际值,而对于其他人,则返回None

代码语言:javascript
复制
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)
票数 0
EN

Stack Overflow用户

发布于 2019-10-11 21:16:25

以下是我将根据评论采取的方法。这里的主要问题是能够在解析器中获得查询所请求的字段列表。为此,我使用了改编自here的代码

代码语言:javascript
复制
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

剩下的应该很简单:

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2021-10-06 20:48:45

目前的答案是过于复杂。只需创建两个ObjectTypes,例如:

代码语言:javascript
复制
class PublicUserType(DjangoObjectType):
    class Meta:
        model = get_user_model()
        fields  = ('id', 'username')

class PrivateUserType(DjangoObjectType):
    class Meta:
        model = get_user_model()

花了4个多小时尝试其他解决方案,然后才意识到它是如此简单

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58322640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档