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.29k stars 768 forks source link

Converters cannot convert datetime.timedelta to float. #348

Open dionyself opened 6 years ago

dionyself commented 6 years ago

hello devs. During a conversation about an issue of graphql-core @jkimbo found a possible error

https://github.com/graphql-python/graphene-django/blob/5051d3bb617ce6977eebc023c958bd10de91fe91/graphene_django/converter.py#L111-L113

raising something like { "message": "float() argument must be a string or a number, not 'datetime.timedelta'" }

you can check https://github.com/graphql-python/graphql-core/issues/150 for more info.

spockNinja commented 6 years ago

Yeah, I can see how that'd be a problem... Even if it could convert, a float doesn't quite capture all of the data in a timedelta.

One possibility would be to add an ObjectType wrapper that pulls out the individual parts of the timedelta and send that, potentially with one property being the "human readable" representation.

Any other ideas?

dionyself commented 6 years ago

I managed to get an human readlable for string type by using duration = graphene.String()

https://github.com/dionyself/leaky/blob/71ec608204a3dd66f2fcd25ff36096ba25eb62bc/warehouses/schema/query/asset.py#L8-L13

We probably won't need and human readable for the Float converter, so using timedelta.total_seconds() is fine... but, i think this works in py3 only

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.

zeth commented 4 years ago

This is a bad bot. This is still an issue.

jkimbo commented 4 years ago

Apologies @zeth , reopening the issue. If you have any time any help with the issue would be most appreciated.

stale[bot] commented 4 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.

jjoocceeee commented 4 years ago

Following

JPGarCar commented 2 years ago

Is help still wanted for this issue? I could give it a stab if yall can tell me what you want the solution to be?

aryadovoy commented 2 years ago

I used custom scalar for DurationField, it has helped:

import datetime as dt
from graphene import Scalar
from graphql.language import ast

class DurationScalar(Scalar):

    @staticmethod
    def serialize(value):
        if isinstance(value, dt.timedelta):
            return str(value).zfill(8)[:-3]

    @staticmethod
    def parse_literal(node):
        if isinstance(node, ast.StringValue):
            delta = node.value.split(':')
            duration = dt.timedelta(hours=delta[0], minutes=delta[1])
            return duration

    @staticmethod
    def parse_value(value):
        delta = value.split(':')
        duration = dt.timedelta(hours=int(delta[0]), minutes=int(delta[1]))
        return duration