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
Silk is a live profiling and inspection tool for the Django framework.

Silk is a live profiling and inspection tool for the Django framework. Silk intercepts and stores HTTP requests and database queries before presenting them in a user interface for further inspection:

Jazzband 3.7k Jan 02, 2023
A simple REST API to manage postal addresses, written in Python/Django.

A simple REST API to manage postal addresses, written in Python/Django.

Attila Bagossy 2 Feb 14, 2022
A pluggable Django application for integrating PayPal Payments Standard or Payments Pro

Django PayPal Django PayPal is a pluggable application that integrates with PayPal Payments Standard and Payments Pro. See https://django-paypal.readt

Luke Plant 672 Dec 22, 2022
A prettier way to see Django requests while developing

A prettier way to see Django requests while developing

Adam Hill 35 Dec 02, 2022
This website serves as an online database (hosted via SQLLite) for fictional businesses in the area to store contact information (name, email, phone number, etc.) for fictional customers.

Django-Online-Business-Database-Project this project is still in progress Overview of Website This website serves as an online database (hosted via SQ

1 Oct 30, 2021
Django API creation with signed requests utilizing forms for validation.

django-formapi Create JSON API:s with HMAC authentication and Django form-validation. Version compatibility See Travis-CI page for actual test results

5 Monkeys 34 Apr 04, 2022
Django's class-based generic views are awesome, let's have more of them.

Django Extra Views - The missing class-based generic views for Django Django-extra-views is a Django package which introduces additional class-based v

Andy Ingram 1.3k Jan 04, 2023
Zendesk Assignment - Django Based Ticket Viewer

Zendesk-Coding-Challenge Django Based Ticket Viewer The assignment has been made using Django. Important methods have been scripted in views.py. Excep

Akash Sampurnanand Pandey 0 Dec 23, 2021
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 09, 2022
React.JS - Django Application Template

OTS React.JS - DJango Web Application (UNTESTED) This repository servers as a template for creating React.JS - Django Web Applications. Note that the

Darryl See Wei Shen 5 Aug 19, 2022
A starter template for building a backend with Django and django-rest-framework using docker with PostgreSQL as the primary DB.

Django-Rest-Template! This is a basic starter template for a backend project with Django as the server and PostgreSQL as the database. About the templ

Akshat Sharma 11 Dec 06, 2022
Realtime data read and write without page refresh using Ajax in Django.

Realtime read-write with AJAX Hey,this is the basic implementation type of ajax realtime read write from the database. where you can insert or view re

Mehedi Hasan 3 Dec 13, 2022
A simple porfolio with Django, Bootstrap and Sqlite3

Django Portofolio Example this is a basic portfolio in dark mode Installation git clone https://github.com/FaztWeb/django-portfolio-simple.git cd djan

Fazt Web 16 Sep 26, 2022
Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes

Bleach Bleach is an allowed-list-based HTML sanitizing library that escapes or strips markup and attributes. Bleach can also linkify text safely, appl

Mozilla 2.5k Dec 29, 2022
Django Course Project - TextCorrector

Django-TextUtils Django Course Project A tool for analyzing text data in Django backend. It is a project where you can do some of the things with you

1 Oct 29, 2021
Developer-friendly asynchrony for Django

Django Channels Channels augments Django to bring WebSocket, long-poll HTTP, task offloading and other async support to your code, using familiar Djan

Django 5.5k Dec 29, 2022
Tools to easily create permissioned CRUD endpoints in graphene-django.

graphene-django-plus Tools to easily create permissioned CRUD endpoints in graphene-django. Install pip install graphene-django-plus To make use of ev

Zerosoft 74 Aug 09, 2022
A Django Online Library Management Project.

Why am I doing this? I started learning 📖 Django few months back, and this is a practice project from MDN Web Docs that touches the aspects of Django

1 Nov 13, 2021
A fresh approach to autocomplete implementations, specially for Django. Status: v3 stable, 2.x.x stable, 1.x.x deprecated. Please DO regularely ping us with your link at #yourlabs IRC channel

Features Python 2.7, 3.4, Django 2.0+ support (Django 1.11 (LTS), is supported until django-autocomplete-light-3.2.10), Django (multiple) choice suppo

YourLabs 1.7k Jan 01, 2023
A beginner django project and also my first Django project which involves shortening of a longer URL into a short one using a unique id.

Django-URL-Shortener A beginner django project and also my first Django project which involves shortening of a longer URL into a short one using a uni

Rohini Rao 3 Aug 08, 2021