Coder Social home page Coder Social logo

graphene-django-extras's Introduction

Banner

Night Coding

Hi there, I'm Ernesto

👨🏽‍💻   A self-motivated tech enthusiast and Python 🐍  evangelist. Actually working as Senior Backend Developer at ISN with Python, Django, Docker, GraphQL and PostgreSQL.

Striving to maintain the perfect balance between It doesn't work...! Why? vs It works...! Why?.

🌱   I'm currently learning Flutter and loving it ❤

👨🏽‍🎓   One of my biggest motivations is to learn.

😍   I love attending developer meetings, conferences, holding workshops, and sharing knowledge.

🤩   Perfect job would be 70% Backend, 20% DevOps, and 10% Frontend.

🙋‍♂️   Pronouns: He/Him

Night Coding

🛠  Tech Stack

Python  Rust  Django  FastAPI  Flask  Docker  GraphQL 
JavaScript  HTML  CSS  React  React Native  Bootstrap  TailwindCSS 
Git  GitHub  Gitlab  Google Cloud Jira 
PyCharm  Visual Studio Code  PostgreSQL 

⚙️  GitHub Analytics

✨ Featured project

🤝🏻  Connect with Me

GitHub Ernesto LinkedIn Email

visitor badge

graphene-django-extras's People

Contributors

alecrosenbaum avatar atomboulian avatar bemcculley avatar bernardopericacho avatar cassiemeharry avatar dreglad avatar eamigo86 avatar ellimilial avatar ernesto-perez-amigo avatar fabienheureux avatar jackton1 avatar jamesmcnamara avatar jonafato avatar jozefsukovsky avatar jstacoder avatar jzelez avatar keithhackbarth avatar kennand avatar ldynia avatar leiserfg avatar mandersennano avatar ollamh avatar ouradze avatar s3rius avatar slurms avatar tadeo avatar tinyjin avatar washeck avatar zagrebelin avatar zulupro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

graphene-django-extras's Issues

Dumb question for __init_subclass_with_meta__

Hi Sir,
Much appreciate for the lib you are working on! i like it very much.
I wonder if you can give me some guidance on how init_subclass_with_meta works,
i keep investigating in the source code and other examples but still can't figure it out.

in this method:

    def __init_subclass_with_meta__(cls, serializer_class=None, only_fields=(), exclude_fields=(),
                                    save_resolver=None, delete_resolver=None,
                                    input_field_name=None, output_field_name=None, description='',
                                    nested_fields=False, **options):

        if not serializer_class:
            raise Exception('serializer_class is required on all DjangoSerializerMutation')

the point confused me is I didn't find anywhere that init_subclass_with_meta get called as a classmethod in my code,
and never manually pass serializer_class into this function, wonder how does line if not serializer_class: working properly? why it can automatically detect i assigned serializer_class in my Meta subclass in which inherited from DjangoSerializerMutation class?

much appreciated!

Expose a way to assign a custom FilterSet to a DjangoObjectType

In django-filter you can declare custom FilterSet, and in graphene-django(-extras) you can use it in a custom resolver, but there is not a way to use it in every point the type is referred. I think that it can be resolved by simply adding a filter_set_class parameter to the DjangoObjectType and using it as default value instead of None in the call to DjangoFilterListField in converter.py.

DRF 3.8 Compatibility

Upgrading to the recently released DRF 3.8.x series broke compatibiliy with graphene-django-extras

In DRF 3.8, rest_framework.compat._resolve_model function has been removed, but it is being imported by utils.py#L15.

I don't feel like opining on the "correct" solution, but since _resolve_model is only used when Django < 1.9, then making it not only 'conditionally used' but also 'conditionally imported' would make sense to me.

Default `DEFAULT_PAGINATION_CLASS` failed

Hey! Thanks for this package 👍

I got exception on using DEFAULT_PAGINATION_CLASS.

settings.py

GRAPHENE_DJANGO_EXTRAS = {
    'DEFAULT_PAGINATION_CLASS': 'graphene_django_extras.paginations.LimitOffsetGraphqlPagination',
    'DEFAULT_PAGE_SIZE': 50,
    'MAX_PAGE_SIZE': 100
}

I'm using DjangoFilterPaginateListField without pagination parameter:

# types.py
class PositionType(DjangoObjectType):
    class Meta:
        model = models.Position
        filter_fields = {
            'name': ['exact', 'icontains', 'istartswith'],
            'id': ['exact']
        }
# schema.py
class Query(ObjectType):
    positions = DjangoFilterPaginateListField(types.PositionType)

Traceback:

File "/usr/local/lib/python3.6/site-packages/graphene_django_extras/fields.py", line 132, in __init__
    ).format(pagination)
AssertionError: You need to pass a valid DjangoGraphqlPagination in DjangoFilterPaginateListField, received "<class 'graphene_django_extras.paginations.pagination.LimitOffsetGraphqlPagination'>".

graphene_django_extras/fields.py

isinstance(pagination, BaseDjangoGraphqlPagination) on 142 line.

Code from sources:

pagination = pagination or graphql_api_settings.DEFAULT_PAGINATION_CLASS
if pagination is not None:
    assert isinstance(pagination, BaseDjangoGraphqlPagination), (
        'You need to pass a valid DjangoGraphqlPagination in DjangoFilterPaginateListField, received "{}".'
    ).format(pagination)

How can I use the decorators in django-graphql-jwt ?

I am using django-graphql-jwt and it exposes a couple of decorators such as @login_required that are used to decorate the resolver functions to restrict their access.

How can I use such decorators with DjangoSerializerType, .ListField(), RetrieveField(), etc. I only want to restrict access for certain fields such as:

import graphene
from .types import UserType


class Query(graphene.ObjectType):
    users = UserType.ListField()
    user = UserType.RetrieveField()


class Mutation(graphene.ObjectType):
    update_user = UserType.UpdateField()

Resolvers are not defined in these cases. Any suggestions on how to make it work with django-graphql-jwt ?

Warining: Abstract type is deprecated

I'm getting this warning when runing my server


/Users/sgaseretto/.virtualenvs/graphene/lib/python3.6/site-packages/graphene/types/abstracttype.py:9: DeprecationWarning: Abstract type is deprecated, please use normal object inheritance instead.
See more: https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#deprecations
  "Abstract type is deprecated, please use normal object inheritance instead.\n"
/Users/sgaseretto/.virtualenvs/graphene/lib/python3.6/site-packages/graphene/types/abstracttype.py:9: DeprecationWarning: Abstract type is deprecated, please use normal object inheritance instead.
See more: https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#deprecations
  "Abstract type is deprecated, please use normal object inheritance instead.\n"
[14/Mar/2018 20:02:27] "POST /graphql/ HTTP/1.1" 200 72700


Any idea of how to avoid it?

Add a way to tag a custom resolver for prefetch

I have a type with a calculated field who depends on a model related field, can you add a way to tag it for prefetch?
My idea:

class PersonType(DjangoObjectType):
    class Meta:
        model = Person
    display = graphene.String()
    
    @dependes_on('user')
    def resolve_display(self, info):
        return str(self.user) 

This way every access to display will implay a fetch of user.

filtering by request data

For example i want to filter articles by current user using DjangoListObjectField or DjangoFilterPaginateListField
I dont see a clean way to do so right now. In django-graphene for DjangoConnectionField i could define resolve_articles field. It doesnt work here.
Other options would be to use django-filter request filtering by defining a custom filterset_class. https://django-filter.readthedocs.io/en/latest/guide/usage.html#filtering-the-primary-qs

But request not passed to filterset at all
https://github.com/eamigo86/graphene-django-extras/blob/master/graphene_django_extras/fields.py#L188 only qs and data passed. Something like request=info.context is missed.

Am i missing something?

TypeError when using GenericForeignKey

'<' not supported between instances of 'GenericForeignKey' and 'DateTimeField'.

The exception is triggered here : https://github.com/eamigo86/graphene-django-extras/blob/master/graphene_django_extras/utils.py#L22 when using a type like this :

class CommentType(DjangoObjectType):
    class Meta:
        model = Comment

For a model like this:

class Comment(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE,)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
    body = models.TextField()

    created_at = models.DateTimeField(auto_now_add=True, editable=False)
    updated_at = models.DateTimeField(auto_now=True, editable=False)

creating nested objects like in DRF

Hello @eamigo86,

I'm having some trouble with creating nested objects like in DRF as explain in your post https://github.com/graphql-python/graphene-django/issues/274#issuecomment-335191042

Here's what I got in serializers.py:

class BookingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Booking
        fields = (
            'status'
        )

class OtherBookingSerializer(serializers.ModelSerializer):
    booking = BookingSerializer()

    class Meta:
        model = OtherBooking
        fields = (
            'id',
            'first_name',
            'last_name',
            'sex',
            'birthday',
            'language',
            'emergency',
            'booking'
        )

    def create(self, validated_data):
        booking_data = validated_data.pop('booking')
        other_booking = OtherBooking.objects.create(**validated_data)
        Booking.objects.create(otherbooking=other_booking, **booking_data)
        return other_booking`

then in GraphQL, following this example : https://user-images.githubusercontent.com/11740026/31345324-090bfc78-acdb-11e7-9194-ad2bb4f8fdaa.png, it says that field 'booking' is required; but when I put it in my query, it says "unknown field"...

for info, here is what I got on schema.py:

class BookingParticipantStatusSerializerMutation(DjangoSerializerMutation):
    """
        DjangoSerializerMutation auto implement Create, Delete and Update functions
    """
    class Meta:
        description = " DRF serializer based Mutation for Users "
        serializer_class = OtherBookingSerializer
        nested_fields = True

class Mutations(graphene.ObjectType):

    create_booking_participant_status = BookingParticipantStatusSerializerMutation.CreateField()
    update_booking_participant_status = BookingParticipantStatusSerializerMutation.UpdateField()`

I'm struggling to find where the problem comes from.
Any help would be much appreciated!

Thanks in advance!

Objects in results array should not be nullable

This a minor but annoying issue when you use a front end tool like Apollo because it results in weaker typing.
It affects graphene-django as well, but I have more confidence in graphene-django-extras to fix it ! :-)
Here it is: results should not be of the form results: [UserType] but results: [UserType!] since returned objects in the array can't be null.
I don't know if it's somehow related, but the same issues applies to related objects resulting from foreign keys or M2M.

Custom Resolver for DjangoFilterPaginateListField/DjangoFilterListField/DjangoListObjectField

Just wondering if it is possible to define custom resolver for the fields exposed by graphene-django-extras.

My project has two Apps (with separate databases) but with relationships across apps.

I would like to use a custom resolver to select related objects where the connection is not defined in the ORM but still have access to pagination and filtering.

I tried to do this as I would in Graphene-Django but the resolver function isn't called when used with any of the fields provided by this library. I tried it with graphene.field and the resolver function is run.

class SiteObjectType(DjangoObjectType):
     class Meta:
        description = "Site model type definition "
        model = models.Site
   
    vehicles = DjangoListObjectField(types.Vehicle)

    def resolve_vehicles(self, info, **kwargs):
        # something like this to select the relevant vehicle objects
        related_vehicles = Vehicles.object.filter(id__in="self.id")
        return related_vehicles

Is this expected behaviour and is there any way around it?

Thanks for the great work on this extension!

Changing some Fields from a DjangoInputObjectType to required=False

I'm trying to create some update mutations, where I don't want to pass some fields, because I don't want to update them.
For example I have this model:

class Pet(models.Model):
    name = models.CharField(max_length=60)
    description = models.TextField(blank=True, null=True)
    owner = models.ForeignKey(settings.AUTH_USER_MODEL)

And the following InputType:

class PetInput(DjangoInputObjectType):
    class Meta:
        model = Pet
        description = 'Pet InputType'

How can I change, for example, the name and owner fields from my InputType in order to make them required=False. As a suggestion, it will be nice adding something like the exclude_fields = ('name', 'owner') that makes them required=False, for example a require_false_fields = ('name', 'owner') I just don't know how something like this could be implemented

How to add request.user to serializer?

The codes seems not passing context to serializer when it's called.
serializer = cls._meta.serializer_class(data=new_obj)

I would like to add request.user when it tries to save, I couldn't find a way to do it.
Anyone has done this before?

DjangoInputObjectType doesn't allow overwriting model fields

Problem

I'm using custom logic for input validation of a model field (like, validate it as a string and then convert it into UUID v.5 before save). So, I have a model and schema defined below:

# models.py
class TestModel(models.Model):
    test_field = models.UUIDField()

# schema.py
class TestModelInput(DjangoInputObjectType):
    test_field = graphene.String(required=True)

    class Meta:
        model = TestModel

class CreateTestModel(graphene.Mutation):

    class Input:
        data = TestModelInput()
    
    @staticmethod
    def mutate(root, info, data):
        # here I convert and save my model

What I expect from printing graphql schema:

input TestModelInput {
  test_field: String!
  ...

What I get:

input TestModelInput {
  test_field: UUID!
  ...

Solution

I found out that in the graphene_django_extras/types.py:182 this line

super(InputObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)

means that the method InputObjectType.__init_subclass_with_meta__ itself is not being called and this class attributes are not being converted into fields. The line should be changed into

super(DjangoInputObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)

to run correctly.

P.S. Thanks for the great package! It saved me lots of work =)

How can i override delete method

Hi,
Thanks for the lib, i like it very much,
quick question is, seems i can't override the delete method,
I want to check if the products owned by current logged in user before i delete it.
but it seems it's never calling delete and never print product in the console,
create, and update working fine

from rest_framework import serializers
from core.models import Product
class ProductSerializer(serializers.Serializer):
     class Meta:
            model = Product
    def create(self, validated_data):
           pass
    def update(self, product, validated_data):
           pass
     def delete(self, product):
            if self.logged_in() and product.user.id == self.user().id:
                print("product", product)
            raise ValidationError(message={"message": "user not logged in"})

(Custom) Django filters not applied

In fields.py in the method list_resolver (around line 227), I see that filterset_class is commented out and not used at all.

This prevents one from applying custom filters from django_filter. For instance, I have the following filter:

class ObjectFilter(django_filters.FilterSet):
    class Meta:
        model = models.Object
        fields = ["id"]

    # sort is not a field on models.Object, it's just a name I have chosen.
    sort = django_filters.OrderingFilter(fields=(
        'id', 'created',
    ))

The problem is that sort is not a field that exists on the Object model, but queryset_factory tries to apply this one in the filter(**kwargs) method of a model.

This generates errors such as:

graphql.error.located_error.GraphQLLocatedError: Cannot resolve keyword 'sort' into field. Choices are: id, created

So it should apply the filterset class, and ensure that non-model fields are not passed to the filter(**kwargs) method.

Get amount of filtered objects returned by DjangoFilterPaginateListField (before pagination)

Hello, is there a direct (clear) way for accessing amount of objects returned by DjangoFilterPaginateListField?
I need amount of filtered objects before they are split to pages.
Example: if I have 10 objects in db, I filter them by some key and I get 7 objects. I will be paginating this result but I still need the number (7) of objects returned by filter.

Thank you!

support auto_camelcase=False

I was happy to learn that graphene added support for turning off camel casing field names.

schema = graphene.Schema(query=Query, auto_camelcase=False)

It all seems to work except for DjangoListObjectType has totalCount. I tried changing it to total_count in the code and was hoping it would get auto-camel cased to totalCount or not depending on the auto_camelcase setting but it didn't.

I don't know the code well enough to provide a PR. Is this something that could be supported?

Hard dependency on `psycopg2`

In converter.py on line 4, fields from PostgreSQL are imported.

These fields are only available when you have the psycopg2 module installed. This module is not listed in setup.py, but I think it is better to not depend on this if the user does not use PostgresQL.

Compatibility Django 2

Hello,

Django-filters version has been pinned to 1.1 due to its incompatibility with django 2 (I assume). As the version 2 has been released, do you know what would be needed to have it updated such that we could use graphene-django-extras with django 2 or is it compatible out of the box ?

Thanks

Feature Request/Estimate - nested_fields as a tuple instead of a Boolean

Hi @eamigo86 , thanks for this great library!!!

Can I make a suggestion?

For our mutations, we have some fields that we would like to pass the Foreign Key ID as an update instead of creating a new object, and some fields that we would like to create a new object through a nested structure. In other words, for some fields we want the result of nested_fields = True (nested object creation), and other fields we want the result of nested_fields = False (IDs passed in).

Do you think it would be better instead of passing a boolean for the nested_fields, pass a list of fields, to allow only nesting the fields that you specify in DjangoSerializerMutation? Similar to only_fields?

For example, below for the Foreign Key of Project and the related_name of "products":

class RoomSerializerMutation(DjangoSerializerMutation):

    class Meta:
        serializer_class = RoomSerializer
        nested_fields = ("project", "products", )

All other Foreign Key fields (including Many to Many, One to One, etc.) would take in an ID.

If you agree, I also wanted to get a general understanding of how much time that would take as well. I forked the repo and have been experimented with it to see what I can do to provide this feature myself, but I'm not very confident that I can do it since the codebase is so large and I am just learning it.

Thanks again!

undocumented feature: defining a DjangoObjectType as baseType for DjangoListObjectType or DjangoSerializerType

Hi,
first of all: awesome package!
I don't really have an issue to report, but a feature that should be documented and was hard for me to find.
My problem was that I intended to use DjangoSerializerType for common queries and mutations. Everything worked fine, apart from including property functions from the django model. I had to define a baseType like this, which worked fine:

class InstrumentType(DjangoObjectType):
    is_at = graphene.Field(LocationType.object_type(), source='is_at')
    class Meta:
        model = Instrument

But then I couldn't use the nice features of DjangoSerializerType or DjangoListObjectType. Then I searched for a long time how to pass that InstrumentType to e.g. a DjangoSerializerType. Finally I found out that you use this line in the types.py to get an already defined baseType from the registry:

output_type = registry.get_type_for_model(model)
if not output_type:
     output_type = factory_type('output', DjangoObjectType, **factory_kwargs)

But this depends on the order of the type definitions in the source code and is real implicit behaviour.
After I found that out, I could use my InstrumentSerializerType with correct custom baseType just like this:

class InstrumentSerializerType(DjangoSerializerType):
    class Meta:
        serializer_class = InstrumentSerializer

I really suggest you document that behaviour, since it's a powerful feature and can also have unexpected negative effects if you don't know about.

Thanks for the nice work,
Greets,
Bene

ImportError: cannot import name 'QUERY_TERMS'

After last update deps for graphene-django-extras from 0.3.8a9
to 0.3.8a10 via renovate my CI test now throwing a error on launching backend. Work fine with 0.3.8a9.



Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/base.py", line 350, in execute
    self.check()
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/base.py", line 379, in check
    include_deployment_checks=include_deployment_checks,
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 60, in _run_checks
    issues.extend(super()._run_checks(**kwargs))
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/management/base.py", line 366, in _run_checks
    return checks.run_checks(**kwargs)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/checks/registry.py", line 71, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/checks/urls.py", line 40, in check_url_namespaces_unique
    all_namespaces = _load_all_namespaces(resolver)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/core/checks/urls.py", line 57, in _load_all_namespaces
    url_patterns = getattr(resolver, 'url_patterns', [])
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/utils/functional.py", line 37, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/urls/resolvers.py", line 533, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/utils/functional.py", line 37, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django/urls/resolvers.py", line 526, in urlconf_module
    return import_module(self.urlconf_name)
  File "/pipeline/source/back/venv/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 678, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/pipeline/source/back/hamachi_gql/urls.py", line 22, in <module>
    from core.gq.views import HamachiGraphQLView
  File "/pipeline/source/back/core/gq/views.py", line 1, in <module>
    from graphene_django_extras.views import AuthenticatedGraphQLView
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django_extras/__init__.py", line 5, in <module>
    from .fields import DjangoObjectField, DjangoFilterListField, DjangoFilterPaginateListField, \
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django_extras/fields.py", line 7, in <module>
    from graphene_django.filter.utils import get_filtering_args_from_filterset
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django/filter/utils.py", line 3, in <module>
    from .filterset import custom_filterset_factory, setup_filterset
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django/filter/filterset.py", line 5, in <module>
    from django_filters import Filter, MultipleChoiceFilter
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django_filters/__init__.py", line 7, in <module>
    from .filterset import FilterSet
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django_filters/filterset.py", line 15, in <module>
    from .filters import (
  File "/pipeline/source/back/venv/lib/python3.6/site-packages/django_filters/filters.py", line 9, in <module>
    from django.db.models.sql.constants import QUERY_TERMS
ImportError: cannot import name 'QUERY_TERMS'

My req file

beautifulsoup4==4.6.3
dj-database-url==0.5.0
Django==2.1
django-admin-interface==0.6.3
django-anymail==3.0
django-colorfield==0.1.15
django-cors-headers==2.4.0
django-extensions==2.1.0
django-fsm==2.6.0
django-graphiql-debug-toolbar==0.1.1
django-graphql-extensions==0.0.4
django-graphql-jwt==0.1.10
django-mail-templated-simple==3.2
graphene==2.1.3
graphene-django==2.1.0
graphene-django-extras==0.3.8a10
Jinja2==2.10
pinax-stripe==4.4.0
psycopg2==2.7.5
pyjade==4.0.0
python-dateutil==2.7.3
python-decouple==3.1
PyYAML==3.13
requests==2.19.1
six==1.11.0
stringcase==1.2.0
matplotlib==2.2.3
zappa==0.46.2
zappa-django-utils==0.4.0
django-storages==1.6.6
boto3==1.7.75
faker==0.9.0
raven==6.9.0
django-constance==2.2.0
django-picklefield==1.0.0
attrs==18.1.0
simplejson==3.16.0
phonenumbers==8.9.10

Idea: expose more details on pagination

This is something that can be useful for pagination:

  • Allow an option to limit the maximum number of results per offset/page query, e.g. PageGraphqlPagination(max_limit=100). This way, someone cannot query all the results.
  • Expose the actual limit that is being applied.

Consider this (dangerous) query:

allUsers() {
    results(limit:9999, offset:5) {
      ...
    }
    totalCount
    limit <-- return the actual limit that is used.
  }
}

Without this information, you cannot calculate the right number of pages, because if you assume that you can request 99,999 items, and there are 1,000 items, you would calculate 1 page. But if the server applies a limit (e.g. 100), there is no way that you can determine the number of pages (1,000).

Work together with django-hvad

Is there any good way to start working with django-hvad?
What i found: it create translations_model attribute in _meta of model. So, minimum we must include fields from this model in _meta.fields.
In my opinion, there is no obvious way to add fields from this model. Of course, we can do it manually for all required fields and resolve them from this model, but i think that it is not pretty.
Also, i tried monkeypatch get_model_fields something like this

old_get_model_fields = converter.get_model_fields
def get_model_fields(model):
    fields = old_get_model_fields(model)
    if hasattr(model._meta, 'translations_model'):
        fields += old_get_model_fields(model._meta.translations_model)
    return fields
converter.get_model_fields = get_model_fields

and then i can get fields of translation model and use it in query as normal. But i do not check something like mutations and monkeypatching also is not good way.
So, how make it more clearly?

iso8601 with django-graphene 2.2

In django-graphene 2.2 iso8601 was removed from requirements
graphql-python/graphene-django@a59f41b

But graphene-django-extras still relies on it, and dont have a requirement for it which will lead into error

Traceback (most recent call last):
File "/pipeline/source/back/venv/lib/python3.6/site-packages/graphene_django_extras/base_types.py", line 13, in
import iso8601
ModuleNotFoundError: No module named 'iso8601'

DjangoSerializerMutation update mutation with unique model fields

With the latest 0.13 update, I ran into an issue with the DjangoSerializerMutation update mutation.

I have a model that defines a unique value...e.g.

class User(models.Model):
    name = models.CharField(max_length=80, blank=False, null=False, unique=True)

When the call to update is made there is a call to full_clean() on the model with the validated serialized data.

cls._meta.model(**serializer.validated_data).full_clean()

This will fail because it will validate that the name field is unique for the model.

The quick fix is to change the line to:

cls._meta.model(**serializer.validated_data).full_clean(validate_unique=False)

or to make the call to full_clean optional for the mutation.

mixed prefetch_related() and select_related()

Hi @eamigo86, thanks for sharing this!

I was struggling with Django ORM errors like:

Invalid field name(s) given in select_related: 'my_field'. Choices are: my_other_field, another_one, ...

In particular, this happens when both querying AND filtering by a many-to-many or one-to-many relation field.

If i'm not missing something, there seems to be a subtle bug over utils.recursive_params() that leads to such fields being used as arguments for prefetch_related (expected) and simultaneously for select_related (unexpected) if they're "visited" more than once within the recursion.

I made a pull request #42 which fixes this issue for me, by adjusting this duplicate-preventing conditional that misidentifies already-added fields meant for prefetch_related as fields meant for select_related.

[Improvement] Partial Update with serializer_class

Hi,

First, thanks for this amazing lib !

I'm wondering if the partial update would be accessible through the class DjangoSerializerMutation ?

At the moment, I use to bypass this issue, the following code:

import functools

def partialclass(cls, *args, **kwds):
	class NewCls(cls):
		__init__ = functools.partialmethod(cls.__init__, *args, **kwds)

	return NewCls

and then

class MediaFeedMutation(DjangoSerializerMutation):
	class Meta:
		serializer_class = partialclass(MediaFeedSerializer, partial=True)

Is there a way to use DjangoListObjectType with related fields?

Using DjangoListObjectType to make a filterable list doesn't make any related field available on the graphql endpoint.

I have a related field called created_by (ForeignKey to User model) but I can't query it on DjangoListObjectField, only on DjangoObjectField. Is there any way I can do that?

DjangoInputObjectType problem and nested serializers

Hi. Thanks for implementing this stuff. I'm playing around with graphene some time and get piss off on things that were easy in DRF.
I've got problem with implementing DjangoInputObjectType.
This is what i get after just copy-pasting code example:

super(InputObjectType, cls).__init_subclass_with_meta__(_meta=_meta, interfaces=interfaces, **options) TypeError: __init_subclass_with_meta__() got an unexpected keyword argument 'interfaces'

Also, i was trying to implement nested serializer like this:
http://www.django-rest-framework.org/api-guide/serializers/#writable-nested-representations
but it doesn't seem to do anything. Is it even posible?

resolve_[field_name] not working for DjangoListObjectField

I've defined a simple DjangoListObjectType with just a model and pagination attributes in the Meta and when added to Query with DjangoListObjectField I can't get the resolve_[field_name] method called.
Is this an intended behavior? How can I intervene the list/queryset? I wanted to filter out some elements.
Just as a reference of my intention:

class Product(models.Model):
    name = models.CharField(max_length=255)
    discontinued = models.BooleanField(default=False)


class ProductListType(DjangoListObjectType):
    class Meta:
        model = Product
        pagination = LimitOffsetGraphqlPagination()


class Query(graphene.ObjectType):
    all_products = DjangoListObjectField(ProductListType)

   def resolve_all_products(self, info, **kwargs):
      qs = Product.objects.all()
      some_parameter = kwargs.get('some_parameter')
      if some_parameter is not None:
          qs.exclude(discontinued=True)
      return qs

Thanks a lot!

Traditional Methods for displaying calculated field not working.

Very possible that I'm missing something, but my model contains this property:

    @property
    def name_string(self):
        return '%s %s %s' % (
            self.model_year,
            self.model_name,
            self.trim
        )

Serializer:

class VehicleSerializer(serializers.ModelSerializer):
    name_string = serializers.ReadOnlyField()

    class Meta:
        model = Vehicle
        fields = '__all__'
        read_only_fields = ('name_string')

SerializerType:

class VehicleModelType(DjangoSerializerType):
    class Meta:
        description = "Vehicle Model Type Definition"
        serializer_class = VehicleSerializer
        pagination = LimitOffsetGraphqlPagination(default_limit=25)
        filter_fields = {
            'stock': ['exact', ],
            'active': ['exact', ],
        }

However, name_string or nameString isn't an option when querying. Not sure if GDE looks for them, or what I need to do?

Fragments not working

First of all: thank you for contributing this! Django is great, GraphQL is great, but Relay was too much for me.

I noticed that queries with fragments are not yet supported. For instance:

query Objects {
  object {
    results(offset: 0, limit: 20) {
      ...ObjectFragment
    }
    totalCount
  }
}

fragment ObjectFragment on ObjectType {
  id
  __typename
}

I have worked around the issue by changing utils.py on line 105, since it looks like that method only optimizes the query:

...
elif hasattr(field, 'selection_set') and field.selection_set:
...

I found something that might help here. See the get_fields method.

Here is a traceback:

Traceback (most recent call last):
  File "/env/lib/python3.6/site-packages/graphql/execution/executor.py", line 191, in resolve_or_error
    return executor.execute(resolve_fn, source, info, **args)
  File "/env/lib/python3.6/site-packages/graphql/execution/executors/sync.py", line 7, in execute
    return fn(*args, **kwargs)
  File "/env/lib/python3.6/site-packages/graphene_django/debug/middleware.py", line 56, in resolve
    promise = next(root, info, **args)
  File "/env/lib/python3.6/site-packages/graphql/execution/middleware.py", line 57, in make_it_promise
    return Promise.resolve(next(*a, **b))
  File "/env/lib/python3.6/site-packages/graphene_django_extras/fields.py", line 229, in list_resolver
    qs = queryset_factory(manager, info.field_asts, filtering_args, **kwargs)
  File "/env/lib/python3.6/site-packages/graphene_django_extras/utils.py", line 131, in queryset_factory
    select_related, prefetch_related = recursive_params(fields_asts[0].selection_set, available_related_fields, select_related, prefetch_related)
  File "/env/lib/python3.6/site-packages/graphene_django_extras/utils.py", line 106, in recursive_params
    a, b = recursive_params(field.selection_set, available_related_fields, select_related, prefetch_related)
  File "/env/lib/python3.6/site-packages/graphene_django_extras/utils.py", line 105, in recursive_params
    elif field.selection_set:
AttributeError: 'FragmentSpread' object has no attribute 'selection_set'

Need to pin packages

graphql-python/graphql-core#201

Hi, our team is experiencing issues with graphql-core 2.1 - all queries are erroring if they have a blank value in any enums in the data response. In order to stop this side effect for now, and in accordance with good practice of pinning versions until testing new versions, please pin the packages.

I have a PR with this fix here: #54
Looks like you have another PR with a similar request here: #53

Thanks! The sooner this is fixed the sooner I can help more.

Mutation error with DjangoSerializerType

Hi, I encountered an error calling mutations on a model implementing DjangoSerializerType
image

It works fine with DjangoSerializerMutation
image

It seems that ok and errors aren't present on the mutation output on DjangoSerializerType

Couldn't make filters work

Hey! Thanks for this amazing utility, definitely it makes using graphene a lot easier with Django.

I'm having this error when trying to implement a filtered query:

Traceback (most recent call last):
  File "/home/miltonln/Proyectos/Swapps/accountant-venv/lib/python3.6/site-packages/graphql/execution/executor.py", line 330, in complete_value_catching_error
    exe_context, return_type, field_asts, info, result)
  File "/home/miltonln/Proyectos/Swapps/accountant-venv/lib/python3.6/site-packages/graphql/execution/executor.py", line 383, in complete_value
    raise GraphQLLocatedError(field_asts, original_error=result)
graphql.error.located_error.GraphQLLocatedError: 'NoneType' object has no attribute '_meta'

this is my DjangoObjectType :

class ProductType(DjangoObjectType):
    class Meta:
        model = Product
        description = "Hey"
        filter_fields = {
            'name': ['icontains']
        }

and this is the query:

class Query(object):
    all_product_categories = graphene.List(ProductCategoryType)
    all_products = graphene.List(ProductType)
    filter_products = DjangoFilterListField(ProductType)

It is correctly connected to the rest of the project schema.

I made some debugging and it seems to be failing in this line, the root param is None

Am I making some mistake or is this an issue for this library?

Thanks for all the help you can provide to me.

Limit the number of subresults of a list

Hi,

I'm wondering if it's possible to limit the number of subresults as on the example:
https://graphql.org/learn/pagination/
Like

query{
  allBrand(brand:"3715ad6b"){
    results{
      name,
      feeds(limit: 2){
        media{
           image @resize(width:30)          
        }
      }
    }
}

or

query{
  allBrand(brand:"3715ad6b"){
    results{
      name,
      feeds(first: 2){
        media{
           image @resize(width:30)          
        }
      }
    }
}

Include and skip missing

When using the provided get_all_directives function, the default skip and include directives are discarded #50

How To Custom Field Filter?

I'm using django-unixtimestampfield, and some error is raised.

File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/graphene_django_extras/fields.py", line 226, in __init__ self.filterset_class = get_filterset_class(filterset_class, **meta) File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/graphene_django_extras/filters/filter.py", line 12, in get_filterset_class return custom_filterset_factory(**meta) File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/graphene_django_extras/filters/filter.py", line 42, in custom_filterset_factory 'Meta': meta_class File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/django_filters/filterset.py", line 71, in __new__ new_class.base_filters = new_class.get_filters() File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/django_filters/filterset.py", line 345, in get_filters filters[filter_name] = cls.filter_for_field(field, field_name, lookup_expr) File "/Users/keyeMyria/envi/for_python/env_demoni/lib/python3.6/site-packages/django_filters/filterset.py", line 377, in filter_for_field ) % (cls.__name__, field_name, lookup_expr, field.__class__.__name__) AssertionError: UserFilterSet resolved field 'created_at' with 'exact' lookup to an unrecognized field type UnixTimeStampField. Try adding an override to 'Meta.filter_overrides'. See: https://django-filter.readthedocs.io/en/master/ref/filterset.html#customise-filter-generation-with-filter-overrides

`

from unixtimestampfield.fields import UnixTimeStampField

class TimestampMixin(models.Model):
created_at = UnixTimeStampField(db_column="crt_at", use_numeric=True, auto_now_add=True, editable=False)
updated_at = UnixTimeStampField(db_column="udt_at", use_numeric=True, auto_now=True)

class Meta:
    abstract = True

`

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.