跳转到主要内容

在graphene中轻松创建受权限的CRUD端点的工具。

项目描述

graphene-django-plus

build status docs status coverage PyPI version python version django version

弃用警告

Graphene本身已被弃用,大多数用户正在迁移到其他更好的替代方案,例如 strawberry

因此,此库正在被弃用,并且将不再为其开发新功能。维护仍将继续,PR仍然受欢迎。

对于寻找替代方案的人来说,我创建了 strawberry-django-plus,不仅可以将其用作迁移到我所维护的项目的方法,还可以添加更多令人惊叹的功能。务必查看它!

graphene-django中轻松创建受权限的CRUD端点的工具。

安装

pip install graphene-django-plus

为了使用此库提供的所有功能,建议安装graphene-django-optimizerdjango-guardian

pip install graphene-django-optimizer django-guardian

功能说明

  • 为Django模型提供一些基本类型,以改善查询
  • 提供一组完整且简单的CRUD突变
    • 处理未认证用户
    • 使用默认的django权限系统进行权限处理
    • 使用django guardian处理对象权限
    • 基于模型自动生成输入(无需编写自己的输入类型或使用django formsdrf serializers
    • 基于模型的验证器自动进行模型验证
  • 非常简单,可以快速为您的模型创建一些CRUD端点
  • 易于扩展和覆盖功能
  • 文件上传处理

包含内容

查看文档获取完整的API文档。

模型

  • graphene_django_plus.models.GuardedModel:一个django模型,可以直接使用或作为混入类。它将提供.has_perm方法和一个.objects.for_user,这些将由下面的ModelType使用以检查对象权限。

类型和查询

  • graphene_django_plus.types.ModelType:通过在设置时进行一些自动prefetch优化,并检查继承自GuardedModel的对象权限,增强了graphene_django_plus.DjangoModelType

  • graphene_django_plus.fields.CountableConnection:增强了graphene.relay.Connection,提供了total_count属性。

以下是一个使用这些内容的示例

import graphene
from graphene import relay
from graphene_django.fields import DjangoConnectionField

from graphene_django_plus.models import GuardedModel
from graphene_django_plus.types import ModelType
from graphene_django_plus.fields import CountableConnection


class MyModel(GuardedModel):
    class Meta:
        # guardian permissions for this model
        permissions = [
            ('can_read', "Can read the this object's info."),
        ]

    name = models.CharField(max_length=255)


class MyModelType(ModelType):
    class Meta:
        model = MyModel
        interfaces = [relay.Node]

        # Use our CountableConnection
        connection_class = CountableConnection

        # When adding this to a query, only objects with a `can_read`
        # permission to the request's user will be allowed to return to him
        # Note that `can_read` was defined in the model.
        # If the model doesn't inherid from `GuardedModel`, `guardian` is not
        # installed or this list is empty, any object will be allowed.
        # This is empty by default
        object_permissions = [
            'can_read',
        ]

        # If unauthenticated users should be allowed to retrieve any object
        # of this type. This is not dependent on `GuardedModel` and neither
        # `guardian` and is defined as `False` by default
        public = False

        # A list of Django model permissions to check. Different from
        # object_permissions, this uses the basic Django's permission system
        # and thus is not dependent on `GuardedModel` and neither `guardian`.
        # This is an empty list by default.
        permissions = []


class Query(graphene.ObjectType):
    my_models = DjangoConnectionField(MyModelType)
    my_model = relay.Node.Field(MyModelType)

可以像这样查询

# All objects that the user has permission to see
query {
  myModels {
    totalCount
    edges {
      node {
        id
        name
      }
    }
  }
}

# Single object if the user has permission to see it
query {
  myModel(id: "<relay global ID>") {
    id
    name
  }
}

突变

  • graphene_django_plus.mutations.BaseMutation:使用relay和基本权限检查的基突变。只需覆盖其.perform_mutation以执行突变。

  • graphene_django_plus.mutations.ModelMutation:可以创建和更新模型(基于输入中是否存在id属性)的模型突变。

  • graphene_django_plus.mutations.ModelCreateMutation:通过从输入中排除id字段来强制执行“仅创建”规则的ModelMutation

  • graphene_django_plus.mutations.ModelUpdateMutation:通过使输入中的id字段为必填来强制执行“仅更新”规则的ModelMutation

  • graphene_django_plus.mutations.ModelDeleteMutation:一个突变,它将仅接收模型的id并将其删除(如果给予权限)。

以下是一个使用这些内容的示例

import graphene
from graphene import relay

from graphene_django_plus.models import GuardedModel
from graphene_django_plus.types import ModelType
from graphene_django_plus.mutations import (
    ModelCreateMutation,
    ModelUpdateMutation,
    ModelDeleteMutation,
)


class MyModel(GuardedModel):
    class Meta:
        # guardian permissions for this model
        permissions = [
            ('can_write', "Can update this object's info."),
        ]

    name = models.CharField(max_length=255)


class MyModelType(ModelType):
    class Meta:
        model = MyModel
        interfaces = [relay.Node]


class MyModelUpdateMutation(ModelUpdateMutation):
    class Meta:
        model = MyModel

        # Make sure only users with the given permissions can modify the
        # object.
        # If the model doesn't inherid from `GuardedModel`, `guardian` is not
        # installed on this list is empty, any object will be allowed.
        # This is empty by default.
        object_permissions = [
            'can_write',
        ]

        # If unauthenticated users should be allowed to retrieve any object
        # of this type. This is not dependent on `GuardedModel` and neither
        # `guardian` and is defined as `False` by default
        public = False

        # A list of Django model permissions to check. Different from
        # object_permissions, this uses the basic Django's permission system
        # and thus is not dependent on `GuardedModel` and neither `guardian`.
        # This is an empty list by default.
        permissions = []


class MyModelDeleteMutation(ModelDeleteMutation):
    class Meta:
        model = MyModel
        object_permissions = [
            'can_write',
        ]


class MyModelCreateMutation(ModelCreateMutation):
    class Meta:
        model = MyModel

    @classmethod
    def after_save(cls, info, instance, cleaned_input=None):
        # If the user created the object, allow him to modify it
        assign_perm('can_write', info.context.user, instance)


class Mutation(graphene.ObjectType):
    my_model_create = MyModelCreateMutation.Field()
    my_model_update = MyModelUpdateMutation.Field()
    my_model_delete = MyModelDeleteMutation.Field()

可以像这样创建/更新/删除

# Create mutation
mutation {
  myModelCreate(input: { name: "foobar" }) {
    myModel {
      name
    }
    errors {
      field
      message
    }
  }
}

# Update mutation
mutation {
  myModelUpdate(input: { id: "<relay global ID>", name: "foobar" }) {
    myModel {
      name
    }
    errors {
      field
      message
    }
  }
}

# Delete mutation
mutation {
  myModelDelete(input: { id: "<relay global ID>" }) {
    myModel {
      name
    }
    errors {
      field
      message
    }
  }
}

任何验证错误都将呈现为errors返回值。

要将自动相关关系添加到突变输入中关闭 - 在您的settings.py中将全局MUTATIONS_INCLUDE_REVERSE_RELATIONS参数设置为False

GRAPHENE_DJANGO_PLUS = {
    'MUTATIONS_INCLUDE_REVERSE_RELATIONS': False
}

注意:如果反向关系没有设置related_name属性 - 突变输入将按Django本身生成的方式生成,即在模型名称的小写版本后追加_set - modelname_set

许可证

本项目受MIT许可协议许可(有关更多信息,请参阅LICENSE

贡献

请确保已安装poetry

使用以下命令安装依赖项

poetry install

使用以下命令运行测试套件

poetry run pytest

请随意fork该项目,并提交包含新特性、修正和翻译的pull requests给我。我们很乐意尽快合并它们并发布新版本。

项目详情


下载文件

下载适用于您的平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源代码分发

graphene_django_plus-5.1.tar.gz (25.0 kB 查看哈希)

上传时间 源代码

构建分发

graphene_django_plus-5.1-py3-none-any.whl (26.5 kB 查看哈希)

上传时间 Python 3

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面