Tools to easily create permissioned CRUD endpoints in graphene.
Project description
graphene-django-plus
Tools to easily create permissioned CRUD endpoints in graphene-django.
Install
pip install graphene-django-plus
To make use of everything this lib has to offer, it is recommended to install both graphene-django-optimizer and django-guardian.
pip install graphene-django-optimizer django-guardian
What is provided
Models
graphene_django_plus.models.GuardedModel
: A django model that can be used either directly or as a mixin. It will provide a.has_perm
method and a.objects.for_user
that will be used byModelType
described bellow to check for object permissions. some utilities to check.
Types and Queries
-
graphene_django_plus.types.ModelType
: This enchancesgraphene_django_plus.DjangoModelType
by doing some automaticprefetch
optimization on setup and also checking for objects permissions on queries when it inherits fromGuardedModel
. -
graphene_django_plus.fields.CountableConnection
: This enchancesgraphene.relay.Connection
to provide atotal_count
attribute.
Here is an example describing how to use those:
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 ot 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 dependant on `GuardedModel` and neither
# `guardian` and is defined as `False` by default
allow_unauthenticated = 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 dependant 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)
This can be queried like:
# 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
}
}
Mutations
-
graphene_django_plus.mutations.BaseMutation
: Base mutation usingrelay
and some basic permission checking. Just override its.perform_mutation
to perform the mutation. -
graphene_django_plus.mutations.ModelMutation
: Model mutation capable of both creating and updating a model based on the existence of anid
attribute in the input. All the model's fields will be automatically read from Django, inserted in the input type and validated. -
graphene_django_plus.mutations.ModelCreateMutation
: AModelMutation
enforcing a "create only" rule by excluding theid
field from the input. -
graphene_django_plus.mutations.ModelUpdateMutation
: AModelMutation
enforcing a "update only" rule by making theid
field required in the input. -
graphene_django_plus.mutations.ModelDeleteMutation
: A mutation that will receive only the model's id and will delete it (if given permission, of course).
Here is an example describing how to use those:
import graphene
from graphene import relay
from graphene_django_plus.models import GuardedModel
from graphene_django_plus.types import ModelType
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 ot 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 dependant on `GuardedModel` and neither
# `guardian` and is defined as `False` by default
allow_unauthenticated = 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 dependant 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()
This can be used to create/update/delete like:
# 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
}
}
}
Any validation errors will be presented in the errors
return value.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for graphene-django-plus-0.2.0.post0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 78e4b5947aa065745f54f31f088b1b5c905cb5033da957bfdea4b387ecaa3971 |
|
MD5 | baaee15990da4f6d1bb60e5aa1c73be9 |
|
BLAKE2b-256 | 1177d9d47c8890222282f6960e04db88420c7b9144821e2f66a513bf5095f671 |
Hashes for graphene_django_plus-0.2.0.post0-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 4b306516601a91828760a0253dae633220c05afcd25615a67472c4516c0e35ca |
|
MD5 | 316906e02eebd7992fd9f6d9ad96feb1 |
|
BLAKE2b-256 | 424f8298a5f8ad7fe8f5bd0553d0167f21ca8459eaac30c113d4fa1c90fe561a |