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
☄️ Google Forms autofill script

lazrr 'Destroy Them With Lazers' - Knife Party, 2011 Google Forms autofill script Installation: pip3 install -r requirements.txt Usage: python3 lazrr.

Serezha Rakhmanov 12 Jun 04, 2022
https://django-storages.readthedocs.io/

Installation Installing from PyPI is as easy as doing: pip install django-storages If you'd prefer to install from source (maybe there is a bugfix in

Josh Schneier 2.3k Jan 06, 2023
Django-Text-to-HTML-converter - The simple Text to HTML Converter using Django framework

Django-Text-to-HTML-converter This is the simple Text to HTML Converter using Dj

Nikit Singh Kanyal 6 Oct 09, 2022
A simple Django dev environment setup with docker for demo purposes for GalsenDev community

GalsenDEV Docker Demo This is a basic Django dev environment setup with docker and docker-compose for a GalsenDev Meetup. The main purposes was to mak

3 Jul 03, 2021
Chatbot for ordering and tracking a Pizza.

Pizza Chatbot To start the app, follow the below steps: Clone the repo using the below command: git clone Shreya Shah 1 Jul 15, 2021

The Django Leaflet Admin List package provides an admin list view featured by the map and bounding box filter for the geo-based data of the GeoDjango.

The Django Leaflet Admin List package provides an admin list view featured by the map and bounding box filter for the geo-based data of the GeoDjango. It requires a django-leaflet package.

Vsevolod Novikov 33 Nov 11, 2022
Django React Project Setup

Django-React-Project-Setup INSTALLATION: python -m pip install drps USAGE: in your cmd: python -m drps Starting fullstack project with Django and Reac

Ghazi Zabalawi 7 Feb 06, 2022
Use Database URLs in your Django Application.

DJ-Database-URL This simple Django utility allows you to utilize the 12factor inspired DATABASE_URL environment variable to configure your Django appl

Jacob Kaplan-Moss 1.3k Dec 30, 2022
A fresh approach to autocomplete implementations, specially for Django.

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

YourLabs 1.6k Dec 22, 2022
Official clone of the Subversion repository.

Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. All documentation is in the "docs" directo

Raymond Penners 3 May 06, 2022
RedisTimeSeries python client

redistimeseries-py Deprecation notice As of redis-py 4.0.0 this library is deprecated. It's features have been merged into redis-py. Please either ins

98 Dec 08, 2022
This repository contains django library management system project.

Library Management System Django ** INSTALLATION** First of all install python on your system. Then run pip install -r requirements.txt to required se

whoisdinanath 1 Dec 26, 2022
Reusable, generic mixins for Django

django-braces Mixins for Django's class-based views. Documentation Read The Docs Installation Install from PyPI with pip: pip install django-braces Bu

Brack3t 1.9k Jan 05, 2023
A simple Blog Using Django Framework and Used IBM Cloud Services for Text Analysis and Text to Speech

ElhamBlog Cloud Computing Course first assignment. A simple Blog Using Django Framework and Used IBM Cloud Services for Text Analysis and Text to Spee

Elham Razi 5 Dec 06, 2022
🌟 A social media made with Django and Python and Bulma. 🎉

Vitary A simple social media made with Django Installation 🛠️ Get the source code 💻 git clone https://github.com/foxy4096/Vitary.git Go the the dir

Aditya Priyadarshi 15 Aug 30, 2022
A simple app that provides django integration for RQ (Redis Queue)

Django-RQ Django integration with RQ, a Redis based Python queuing library. Django-RQ is a simple app that allows you to configure your queues in djan

RQ 1.6k Jan 06, 2023
Domain-driven e-commerce for Django

Domain-driven e-commerce for Django Oscar is an e-commerce framework for Django designed for building domain-driven sites. It is structured such that

Oscar 5.6k Jan 01, 2023
The best way to have DRY Django forms. The app provides a tag and filter that lets you quickly render forms in a div format while providing an enormous amount of capability to configure and control the rendered HTML.

django-crispy-forms The best way to have Django DRY forms. Build programmatic reusable layouts out of components, having full control of the rendered

4.6k Jan 07, 2023
Add Chart.js visualizations to your Django admin using a mixin class

django-admincharts Add Chart.js visualizations to your Django admin using a mixin class. Example from django.contrib import admin from .models import

Dropseed 22 Nov 22, 2022
Boilerplate Django Blog for production deployments!

CFE Django Blog THIS IS COMING SOON This is boilerplate code that you can use to learn how to bring Django into production. TLDR; This is definitely c

Coding For Entrepreneurs 26 Dec 09, 2022