Tools to easily create permissioned CRUD endpoints in graphene-django.

Overview

graphene-django-plus

build status docs status coverage PyPI version python version django version

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 it does

  • Provides some base types for Django Models to improve querying them with:
  • Provides a set of complete and simple CRUD mutations with:
    • Unauthenticated user handling
    • Permission handling using the default django permission system
    • Object permission handling using django guardian
    • Automatic input generation based on the model (no need to write your own input type or use django forms and drf serializers)
    • Automatic model validation based on the model's validators
  • Very simple to create some quick CRUD endpoints for your models
  • Easy to extend and override functionalities
  • File upload handling

What is included

Check the docs for a complete api documentation.

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 by ModelType described bellow to check for object permissions. some utilities to check.

Types and Queries

  • graphene_django_plus.types.ModelType: This enchances graphene_django_plus.DjangoModelType by doing some automatic prefetch optimization on setup and also checking for objects permissions on queries when it inherits from GuardedModel.

  • graphene_django_plus.fields.CountableConnection: This enchances graphene.relay.Connection to provide a total_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 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 dependant 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 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:

") { id name } } ">
# 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: "
    
     "
    ) {
    id
    name
  }
}

Mutations

  • graphene_django_plus.mutations.BaseMutation: Base mutation using relay 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 an id 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: A ModelMutation enforcing a "create only" rule by excluding the id field from the input.

  • graphene_django_plus.mutations.ModelUpdateMutation: A ModelMutation enforcing a "update only" rule by making the id 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
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 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
        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 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:

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

# Update mutation
mutation {
  myModelUpdate(input: {id: "
    
     "
     name: "foobar"}) {
    myModel {
      name
    }
    errors {
      field
      message
    }
  }
}

# Delete mutation
mutation {
  myModelDelete(input: {id: "
    
     "
    }) {
    myModel {
      name
    }
    errors {
      field
      message
    }
  }
}

Any validation errors will be presented in the errors return value.

To turn off auto related relations addition to the mutation input - set global MUTATIONS_INCLUDE_REVERSE_RELATIONS parameter to False in your settings.py:

GRAPHENE_DJANGO_PLUS = {
    'MUTATIONS_INCLUDE_REVERSE_RELATIONS': False
}

Note: in case reverse relation does not have related_name attribute set - mutation input will be generated as Django itself is generating by appending _set to the lower cased model name - modelname_set

License

This project is licensed under MIT licence (see LICENSE for more info)

Contributing

Make sure to have poetry installed.

Install dependencies with:

poetry install

Run the testsuite with:

poetry run pytest

Feel free to fork the project and send me pull requests with new features, corrections and translations. We'll gladly merge them and release new versions ASAP.

Comments
  • Issues with new 2.3 release

    Issues with new 2.3 release

    As I've installed new 2.3 release I've faces several issues, which firstly I want to bring up for a discussion and upon an approval - I could create a PR for fixing. Issues are as following:

    1. Schema is unable to generate related fields in case they are not defined, I mean in case we have ForeignKey without related_name definition:
    class Father(models.Model):
       name = CharField(max_length=256, db_index=True)
    
    class Son(models.Model):
       name = CharField(max_length=256, db_index=True)
       father = ForeignKey(Father, on_delete=CASCADE)
    

    As far as I've debugged - in case FK field does not have related_name attribute it's not added as son_set field either (I think it comes up from this line https://github.com/0soft/graphene-django-plus/blob/master/graphene_django_plus/mutations.py#L97). I believe this can bring a very big confuse as Django does not force you to put related_name attribute 2. Basically now by default related son objects can be assigned to Father (following the previous example) while you wouldn't even think about that since it's not directly in the model when creating a mutation, right?I believe this might bring some logic-related security issues for some projects. What I'd suggest is that this possibility is really great, but I'd expect that to be added only when I explicitly add related_name in fields of mutation:

    class UpdateFather(ModelUpdateMutation):
       class Meta:
          model = Father
          only_fields = ["name", "sons"]  # While it wouldn't be possible to update sons relation in case it's not in `only_fields` (`only_fields` are not defined at all)
    

    What are your ideas about that?

    opened by justinask7 10
  • When and where to set some field value before mutation?

    When and where to set some field value before mutation?

    Hello, I have a model that has a "owner" field with it.

    I have two questions:

    1. how can i make this field not required or even hidden on graphql api?
    2. how can i set it to the request user before save? or raise error when the both do not match if Q1 can not be solved.

    Looking forward to your reply.

    opened by Rainshaw 6
  • Support for the use of different registries

    Support for the use of different registries

    Until now it is not possible with graphene_django_plus to use more than one ModelType for a django model, because internally the global registry is always used. This pull request adds support for a registry parameter analogous to the registry parameter in DjangoObjectType for mutations.

    opened by RainerHausdorf 5
  • #support #UploadType

    #support #UploadType

    Hey, guys... I need your help.

    How I can test a mutations with UploadType.

    Our model Post

    
    class Post(Resource):
        image = models.ImageField(upload_to="post")
    

    And my Test

    class PostTestCase(JSONWebTokenTestCase):
        
        def setUp(self):
            self.post = PostFactory
    
        def test_create(self):
    
            post = self.post.build()
    
            query = '''
                mutation($input: PostCreateInput!) {
                    postCreate(input: $input) {
                        post{
                            id
                            image
                        }
                    }
                }
            '''
    
            response = self.client.post(
                '/graphql',
                data={
                    'operations': json.dumps({
                        'query': query,
                        'variables': {
                            'input': {
                                'image': None
                            },
                        },
                    }),
                    't_file': post.image,
                    'map': json.dumps({
                        't_file': ['variables.input.image'],
                    }),
                }
            )
    
            print(response)
    

    And the response

    Creating test database for alias 'default'...
    System check identified no issues (0 silenced).
    <WSGIRequest: POST '/graphql'>
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.087s
    
    OK
    Destroying test database for alias 'default'...
    

    The file doesn't upload!

    opened by nietzscheson 4
  • ModelCreateMutation generates required fields for CharFields without null=True.

    ModelCreateMutation generates required fields for CharFields without null=True.

    Django discourages the use of null=True for CharFields (and other fields based on CharField, like URLField etc) - https://docs.djangoproject.com/en/3.0/ref/models/fields/#null.

    But the mutation types generates required input parameters for such fields. It should look at the 'blank' property of the field for CharField and TextField to decide if it's required or not.

    opened by gghildyal 4
  • Register input types for model fields

    Register input types for model fields

    Right now the input fields for the mutations are returned from the method _get_fields. Depending on the model field class, it returns a certain type of graphene scalar to be used as input type. This PR moves that logic into a function called get_input_type which provides different variants for different model fields. This makes it possible to register new input types for custom model fields.

    opened by joricht 3
  • Bump django from 3.2.13 to 3.2.14

    Bump django from 3.2.13 to 3.2.14

    Bumps django from 3.2.13 to 3.2.14.

    Commits
    • 746e88c [3.2.x] Bumped version for 3.2.14 release.
    • a9010fe [3.2.x] Fixed CVE-2022-34265 -- Protected Trunc(kind)/Extract(lookup_name) ag...
    • 3acf156 [3.2.x] Fixed GEOSTest.test_emptyCollections() on GEOS 3.8.0.
    • 4a5d98e [3.2.x] Bumped minimum Sphinx version to 4.5.0.
    • 1a90981 [3.2.x] Fixed docs build with sphinxcontrib-spelling 7.5.0+.
    • 37f4de2 [3.2.x] Added stub release notes for 3.2.14.
    • 7595f76 [3.2.x] Fixed test_request_lifecycle_signals_dispatched_with_thread_sensitive...
    • 2dc85ec [3.2.x] Fixed CoveringIndexTests.test_covering_partial_index() when DEFAULT_I...
    • a23c25d [3.2.x] Fixed #33753 -- Fixed docs build on Sphinx 5+.
    • e01b383 [3.2.x] Added CVE-2022-28346 and CVE-2022-28347 to security archive.
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 2
  • 'FloatField' object has no attribute 'max_digits'

    'FloatField' object has no attribute 'max_digits'

    The last pipeline of my project worked correctly. This was two weeks ago. This week there have been several problems with this library. Now it is throwing me this error: 'FloatField' object has no attribute 'max_digits'

    For Django Float and Decimal are different: https://github.com/0soft/graphene-django-plus/blob/master/graphene_django_plus/schema.py#L116-L117

    opened by nietzscheson 2
  • Check object_permissions argument before check permission inside get_node on ModelType class

    Check object_permissions argument before check permission inside get_node on ModelType class

    Hi,

    I have notice that inside get_node method in ModelType class before check permission at this point is not checked if cls has a object_permissions attribute inside Meta class.

    it's right ?

    Thanks for the attention and the job for the library :)

    opened by eikichi18 2
  • Reverse relations input in mutations update

    Reverse relations input in mutations update

    • Added global settings.
    • Fixed relation without related_name ObjectType creation (will be added as modelname_set)
    • Added possibility to turn off auto related-name generation for mutations through global setting

    This PR is for resolving issue https://github.com/0soft/graphene-django-plus/issues/13

    opened by justinask7 2
  • Order of imports affects the operation of the library

    Order of imports affects the operation of the library

    First of all, I would like to thank you for piece of good work. Inspired by @mirumee guys, I wanted to write something similar, but found your library.

    I like to keep the following Django application structure:

    books
    ├── models.py
    ├── mutations.py
    ├── schema.py
    └── types.py
    

    In schema I put everything together. I noticed when types are imported after mutations:

    from .mutations import BookCreateMutation, BookUpdateMutation
    from .types import BookType
    

    Django/Graphene throws the following exception: django.core.exceptions.ImproperlyConfigured: Unable to find type for model Book in graphene registry

    When types are imported before mutations application starts normally. This is a little problematic because isort changes the order, which makes it necessary to disable sorting in all my schema.py files.

    I haven't had time to dig into your code, but maybe you can tell me the potential cause of my problem?

    opened by lswierszcz 2
  • Bump certifi from 2021.10.8 to 2022.12.7

    Bump certifi from 2021.10.8 to 2022.12.7

    Bumps certifi from 2021.10.8 to 2022.12.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 1
  • Bump django from 3.2.13 to 3.2.15

    Bump django from 3.2.13 to 3.2.15

    Bumps django from 3.2.13 to 3.2.15.

    Commits
    • 653a7bd [3.2.x] Bumped version for 3.2.15 release.
    • b3e4494 [3.2.x] Fixed CVE-2022-36359 -- Escaped filename in Content-Disposition header.
    • cb7fbac [3.2.x] Fixed collation tests on MySQL 8.0.30+.
    • 840d009 [3.2.x] Fixed inspectdb and schema tests on MariaDB 10.6+.
    • a5eba20 Adjusted release notes for 3.2.15.
    • ad104fb [3.2.x] Added stub release notes for 3.2.15 release.
    • 22916c8 [3.2.x] Fixed RelatedGeoModelTest.test08_defer_only() on MySQL 8+ with MyISAM...
    • e1cfbe5 [3.2.x] Added CVE-2022-34265 to security archive.
    • 605cf0d [3.2.x] Post-release version bump.
    • 746e88c [3.2.x] Bumped version for 3.2.14 release.
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • This lib is DEPRECATED (read this)

    This lib is DEPRECATED (read this)

    Graphene itself is abandoned and most users are migrating to other better alternatives, like strawberry.

    For that reason this lib is being deprecated and new features will no longer be developed for it. Maintenance is still going to happen and PRs are still welcomed though.

    For anyone looking for alternatives, I created strawberry-django-plus to use not only as a migration path to the projects I maintain, but also to add even more awesome features. Be sure to check it out!

    opened by bellini666 0
  • Any plans on merging this functionality with graphene-django?

    Any plans on merging this functionality with graphene-django?

    I really like how you have constructed the serializer mutations. It would be nice to have "RelaySerializerMutation" like this in graphene-django. The permissions are a nice touch as well. Any reason why this is a separate project? Is there a long term goal of making this part of graphene-django?

    opened by jottenlips 2
Releases(v4.5)
  • v4.5(Jan 28, 2022)

  • v4.4(Dec 7, 2021)

    What's Changed

    • Support for the use of different registries by @RainerHausdorf in https://github.com/0soft/graphene-django-plus/pull/30
    • Register input types for model fields by @joricht in https://github.com/0soft/graphene-django-plus/pull/32

    New Contributors

    • @RainerHausdorf made their first contribution in https://github.com/0soft/graphene-django-plus/pull/30
    • @joricht made their first contribution in https://github.com/0soft/graphene-django-plus/pull/32

    Full Changelog: https://github.com/0soft/graphene-django-plus/compare/v4.0.4...v4.4

    Source code(tar.gz)
    Source code(zip)
  • v4.3(Nov 22, 2021)

    Possible breaking change

    • The ModelMutation used to generate the default return value of the model as snake_case. So, the model FooBar would be set to fooBar. That still works the same for the endpoint, but in python it is weird to have to return cls(fooBar=instance). This changes the default attribute to use foo_bar .

    Full Changelog: https://github.com/0soft/graphene-django-plus/compare/v4.0.4...v4.3

    Source code(tar.gz)
    Source code(zip)
  • v4.2(Nov 17, 2021)

    What's Changed

    • Quote ObjectPermissionChecker so it is not required at runtime (https://github.com/0soft/graphene-django-plus/issues/31)
    • Improve typing overall (NOTE: It is recommente to use the latest version from https://github.com/sbdchd/django-types for an awesome typing experience)

    Full Changelog: https://github.com/0soft/graphene-django-plus/compare/v4.0.4...v4.2

    Source code(tar.gz)
    Source code(zip)
  • v4.1(Nov 16, 2021)

    What's Changed

    • Support for the use of different registries by @RainerHausdorf in https://github.com/0soft/graphene-django-plus/pull/30

    New Contributors

    • @RainerHausdorf made their first contribution in https://github.com/0soft/graphene-django-plus/pull/30

    Full Changelog: https://github.com/0soft/graphene-django-plus/compare/v4.0.4...v4.1

    Source code(tar.gz)
    Source code(zip)
  • v4.0.4(Oct 29, 2021)

  • v4.0.3(Oct 20, 2021)

  • v4.0.2(Oct 17, 2021)

    • Add resolver info typing to all types/queries/mutations

    Full Changelog: https://github.com/0soft/graphene-django-plus/compare/v4.0.1...v4.0.2

    Source code(tar.gz)
    Source code(zip)
  • v4.0.1(Oct 16, 2021)

  • v4.0(Oct 16, 2021)

    • Save m2m fields after calling .before_save and obj.save(), but before .after_save on ModelMutations (will be breaking a breaking change if you depended on the previous functionality for some reason)

    Full Changelog: https://github.com/0soft/graphene-django-plus/compare/v3.1.3...v4.0

    Source code(tar.gz)
    Source code(zip)
  • v3.0(Jul 19, 2021)

    New release which tries to fix some non-stardalized method signatures and other historical issues.

    Note that this release has some breaking changes that need to be fixed if you relied on them:

    • New GuardedRelatedModel that allows to define models that actually relies on a related (i.e. through a foreign key) model's permissions: https://github.com/0soft/graphene-django-plus/commit/d10dccb3e502155f7e51518d638ed824ff8034cc
    • BREAKING CHANGE defaults any_perm checking to True to make it closer to how guardian works: https://github.com/0soft/graphene-django-plus/commit/5425234e22942fb3b796e03c13999804bc143d35 . Change your type meta options if you don't want that
    • BREAKING CHANGE created_at, updated_at and archived_at are not excluded from mutations by default: https://github.com/0soft/graphene-django-plus/commit/c8cf295d9c9fbcc0aabbb6b2d05e1289cd1972eb . Use exclude_fields to exclude those if those are present in your model and you want to exclude them
    • BREAKING CHANGE allow_unauthenticated is now called public to avoid confusion that the name could cause: https://github.com/0soft/graphene-django-plus/commit/e29240bb49936558c0ac5f23b90ff2d3d72f0ea1 . Just change all occurrencies from allow_unauthenticated to public and you should be fine
    • Adjust all mutation's apis to receive info as their first argument: https://github.com/0soft/graphene-django-plus/commit/7a9036ca1f994c3978fce95c623f682e3113c93d . This is a historical problem in which not all apis had a startalized access method and the lack of info prevented some overrides to access it.
    Source code(tar.gz)
    Source code(zip)
  • v2.7(Jul 12, 2021)

  • v2.6.1(Jun 1, 2021)

  • v2.6(Jun 1, 2021)

    BREAKING CHANGES

    • Consider global permissions when checking obj.has_perm. This means that giving a user a global permission for a model will make it reply True when checking for permissions to any object of that model
    • Queries and mutations don't raise PermissionDenied anymore. Instead, queries will return null when the user doesn't have permission to see that object and mutations will swallow the exception and return them in the errors list. To keep the old behaviour you can set the MUTATIONS_SWALLOW_PERMISSIONS = False in settings.
    Source code(tar.gz)
    Source code(zip)
  • v2.5(Jun 1, 2021)

    BREAKING CHANGE

    • GuardedModelManager.for_user now defaults its with_superuser to True to keep compatibility with the default guardian behaviour. If you were using this integration before and needs the old behaviour, you can subclass GuardedModelManager and override its for_user method to keep the old behaviour.
    Source code(tar.gz)
    Source code(zip)
  • v2.4.7(May 23, 2021)

  • v2.4.6(May 17, 2021)

  • v2.4.5(May 16, 2021)

  • v2.4.4(May 14, 2021)

  • v2.4.3(May 13, 2021)

  • v2.4.2(May 13, 2021)

  • v2.4.1(Apr 27, 2021)

  • v2.4.0(Apr 21, 2021)

    • Fix exclude_field when clean instance #22
    • Fix required fields with default value in create mutation #21
    • Experimental query to retrieve mutations input information to make it easier for frontends to build forms
    • Start using poetry for managing dependencies and the build process
    Source code(tar.gz)
    Source code(zip)
Owner
Zerosoft
Software Factory
Zerosoft
A Django GraphQL (Graphene) base template

backend A Django GraphQL (Graphene) base template Make sure your IDE/Editor has Black and EditorConfig plugins installed; and configure it lint file a

Reckonsys 4 May 25, 2022
Django models and endpoints for working with large images -- tile serving

Django Large Image Models and endpoints for working with large images in Django -- specifically geared towards geospatial tile serving. DISCLAIMER: th

Resonant GeoData 42 Dec 17, 2022
A Django Webapp performing CRUD operations on Library Database.

CRUD operations - Django Library Database A Django Webapp performing CRUD operations on Library Database. Tools & Technologies used: Django MongoDB HT

null 1 Dec 5, 2021
CRUD with MySQL, Django and Sass.

CRUD with MySQL, Django and Sass. To have the same data in db: insert into crud_employee (first_name, last_name, email, phone, location, university) v

Luis Quiñones Requelme 1 Nov 19, 2021
Django CRUD REST API Generator

Django CRUD REST API Generator This is a simple tool that generates a Django REST API with the given models. Specs: Authentication, DRF generic views,

Mehmet Alp Sümer 57 Nov 24, 2022
Projeto Crud Django and Mongo

Projeto-Crud_Django_and_Mongo Configuração para rodar o projeto Download Project

Samuel Fernandes Oliveira 2 Jan 24, 2022
Django project starter on steroids: quickly create a Django app AND generate source code for data models + REST/GraphQL APIs (the generated code is auto-linted and has 100% test coverage).

Create Django App ?? We're a Django project starter on steroids! One-line command to create a Django app with all the dependencies auto-installed AND

imagine.ai 68 Oct 19, 2022
Notes-Django: an advanced project to save notes in Django. where users are able to Create, Read, Update and Delete their notes.

An advanced software to keep you notes. It allows users to perform CRUD operations on theirs Notes. Was implemented Authorization and Authentication

Edilson Pateguana 1 Feb 5, 2022
Django URL Shortener is a Django app to to include URL Shortening feature in your Django Project

Django URL Shortener Django URL Shortener is a Django app to to include URL Shortening feature in your Django Project Install this package to your Dja

Rishav Sinha 4 Nov 18, 2021
Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files.

Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards in settings file paths and mark setti

Nikita Sobolev 940 Jan 3, 2023
A drop-in replacement for django's ImageField that provides a flexible, intuitive and easily-extensible interface for quickly creating new images from the one assigned to the field.

django-versatileimagefield A drop-in replacement for django's ImageField that provides a flexible, intuitive and easily-extensible interface for creat

Jonathan Ellenberger 490 Dec 13, 2022
Django Serverless Cron - Run cron jobs easily in a serverless environment

Django Serverless Cron - Run cron jobs easily in a serverless environment

Paul Onteri 41 Dec 16, 2022
Create a netflix-like service using Django, React.js, & More.

Create a netflix-like service using Django. Learn advanced Django techniques to achieve amazing results like never before.

Coding For Entrepreneurs 67 Dec 8, 2022
DCM is a set of tools that helps you to keep your data in your Django Models consistent.

Django Consistency Model DCM is a set of tools that helps you to keep your data in your Django Models consistent. Motivation You have a lot of legacy

Occipital 59 Dec 21, 2022
Meta package to combine turbo-django and stimulus-django

Hotwire + Django This repository aims to help you integrate Hotwire with Django ?? Inspiration might be taken from @hotwired/hotwire-rails. We are sti

Hotwire for Django 31 Aug 9, 2022
django-reversion is an extension to the Django web framework that provides version control for model instances.

django-reversion django-reversion is an extension to the Django web framework that provides version control for model instances. Requirements Python 3

Dave Hall 2.8k Jan 2, 2023
Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.

Django-environ django-environ allows you to use Twelve-factor methodology to configure your Django application with environment variables. import envi

Daniele Faraglia 2.7k Jan 7, 2023
Rosetta is a Django application that eases the translation process of your Django projects

Rosetta Rosetta is a Django application that facilitates the translation process of your Django projects. Because it doesn't export any models, Rosett

Marco Bonetti 909 Dec 26, 2022
Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly.

Cookiecutter Django Powered by Cookiecutter, Cookiecutter Django is a framework for jumpstarting production-ready Django projects quickly. Documentati

Daniel Feldroy 10k Dec 31, 2022