graphql-python / graphene-django

Build powerful, efficient, and flexible GraphQL APIs with seamless Django integration.
http://docs.graphene-python.org/projects/django/en/latest/
MIT License
4.31k stars 770 forks source link

Field for Postgres RangeField not work on Django 2.2.x( at least) #675

Open sprhawk opened 5 years ago

sprhawk commented 5 years ago

I'm using Django 2.2.x, graphene-django 2.3.0

I use a Postgres DateTimeRangeField, but GraphQL reports error ""User Error: expected iterable, but did not find one for field XXX"

I digged in, and found in graphql: execution/executor.py

586     assert isinstance(result, Iterable), (
587         "User Error: expected iterable, but did not find one " + "for field {}.{}."
588     ).format(info.parent_type, info.field_name)

where result is NonNull, inside is DateTimeTZRange. which is not declared List(DateTime) declared inside graphene-django converter.py

 233 @convert_django_field.register(RangeField)
 234 def convert_posgres_range_to_string(field, registry=None):
 235     inner_type = convert_django_field(field.base_field)
 236     if not isinstance(inner_type, (List, NonNull)):
 237         inner_type = type(inner_type)
 238     return List(inner_type, description=field.help_text, required=not field.null)

I want to define a data type to show structure for Range like:

{
    lower
    upper
    bounds
}

which will introduce break changes to current API.

is it OK to do this. or what else better solution to this?

stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

elcolie commented 4 years ago

This problem still persist with Django3. Here is simple code to get the same error

from django.contrib.postgres.fields import DecimalRangeField
from django.db import models

class Premium(models.Model):
    percentage = models.DecimalField(max_digits=10, decimal_places=2)
    sum_insured = DecimalRangeField()   # Insurer accepts this range

    def __str__(self):
        return f"{self.percentage} | {self.sum_insured}"
from graphene import relay
from graphene_django import DjangoObjectType

from experiment_django3.insurances.models import Premium

class PremiumNode(DjangoObjectType):
    class Meta:
        model = Premium
        filter_fields = [
            'percentage',
            'sum_insured',
        ]
        interfaces = (relay.Node,)
artdiev commented 4 years ago

Still a problem

dejanjovicic22 commented 1 year ago

Still a problem

aradkdj commented 8 months ago

Sorry to bump this, but it's been almost a year since the last comment. Today I hit this andgot as far as OP, also willing to make a PR if it would be welcomed

kiendang commented 8 months ago

@aradkdj Yes a PR would be very much welcomed.