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
Forward and backwards compatibility layer for Django 1.4, 1.7, 1.8, 1.9, 1.10, and 1.11

django-compat Forward and backwards compatibility layer for Django 1.4 , 1.7 , 1.8, 1.9, 1.10 and 1.11 Consider django-compat as an experiment based o

arteria GmbH 106 Mar 28, 2022
A simple demonstration of integrating a sentiment analysis tool in a django project

sentiment-analysis A simple demonstration of integrating a sentiment analysis tool in a django project (watch the video .mp4) To run this project : pi

2 Oct 16, 2021
Plug and play continuous integration with django and jenkins

django-jenkins Plug and play continuous integration with Django and Jenkins Installation From PyPI: $ pip install django-jenkins Or by downloading th

Mikhail Podgurskiy 941 Oct 22, 2022
Packs a bunch of smaller CSS files together from 1 folder.

Packs a bunch of smaller CSS files together from 1 folder.

1 Dec 09, 2021
Wrapping Raml around Django rest-api's

Ramlwrap is a toolkit for Django which allows a combination of rapid server prototyping as well as enforcement of API definition from the RAML api. R

Jmons 8 Dec 27, 2021
based official code from django channels, replace frontend with reactjs

django_channels_chat_official_tutorial demo project for django channels tutorial code from tutorial page: https://channels.readthedocs.io/en/stable/tu

lightsong 1 Oct 22, 2021
Django-Audiofield is a simple app that allows Audio files upload, management and conversion to different audio format (mp3, wav & ogg), which also makes it easy to play audio files into your Django application.

Django-Audiofield Description: Django Audio Management Tools Maintainer: Areski Contributors: list of contributors Django-Audiofield is a simple app t

Areski Belaid 167 Nov 10, 2022
Comprehensive Markdown plugin built for Django

Django MarkdownX Django MarkdownX is a comprehensive Markdown plugin built for Django, the renowned high-level Python web framework, with flexibility,

neutronX 738 Dec 21, 2022
Django StatusPage - App to display statuspage for your services

Django StatusPage - App to display statuspage for your services

Gorlik 1 Oct 27, 2021
Django React - Purity Dashboard (Open-Source) | AppSeed

Django React Purity Dashboard Start your Development with an Innovative Admin Template for Chakra UI and React. Purity UI Dashboard is built with over

App Generator 19 Sep 19, 2022
A simple polling app made in Django and Bootstrap

DjangoPolls A Simple Polling app made with Django Instructions Make sure you have Python installed Step 1. Open a terminal Step 2. Paste the given cod

Aditya Priyadarshi 1 Nov 10, 2021
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
Simply integrate Summernote editor with Django project.

django-summernote Summernote is a simple WYSIWYG editor. django-summernote allows you to embed Summernote into Django very handy. Support admin mixins

Summernote 936 Jan 02, 2023
A debug/profiling overlay for Django

Django Debug Toolbar The Django Debug Toolbar is a configurable set of panels that display various debug information about the current request/respons

David Cramer 228 Oct 17, 2022
Median and percentile for Django and MongoEngine

Tailslide Median and percentile for Django and MongoEngine Supports: PostgreSQL SQLite MariaDB MySQL (with an extension) SQL Server MongoDB 🔥 Uses na

Andrew Kane 4 Jan 15, 2022
Django Girls Tutorial Workshop

Django Girls Tutorial Workshop A log of activities during the workshop. this is an H2 git remote add origin https://github.com/ahuimanu/django_girls_t

Jeffry Babb 1 Oct 27, 2021
PostgreSQL with Docker + Portainer + pgAdmin + Django local

django-postgresql-docker Running PostgreSQL with Docker + Portainer + pgAdmin + Django local for development. This project was done with: Python 3.9.8

Regis Santos 4 Jun 12, 2022
Django query profiler - one profiler to rule them all. Shows queries, detects N+1 and gives recommendations on how to resolve them

Django Query Profiler This is a query profiler for Django applications, for helping developers answer the question "My Django code/page/API is slow, H

Django Query Profiler 116 Dec 15, 2022
💨 Fast, Async-ready, Openapi, type hints based framework for building APIs

Fast to learn, fast to code, fast to run Django Ninja - Fast Django REST Framework Django Ninja is a web framework for building APIs with Django and P

Vitaliy Kucheryaviy 3.8k Jan 01, 2023
Serve files with Django.

django-downloadview django-downloadview makes it easy to serve files with Django: you manage files with Django (permissions, filters, generation, ...)

Jazzband 328 Dec 07, 2022