Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 13951

How to create custom filter using graphene-django and Relay that use multiple fields of different types?

$
0
0

Problem

Hello,

I'm using Graphene Django and Graphene Relay with Python 3.7. I'm trying to make a custom filter for the requests in GraphQL using Django filters.

My table looks like this:

| id(type: int) | flow(type: varchar) | datetime(type: datetime) | duration(type: int) ||---------------|---------------------|--------------------------|---------------------|| 1             | aaa                 | 2019-07-06 08:59:00      | 113095465           || 2             | xxx                 | 2019-07-06 08:59:00      | 113095465           || 3             | bbb                 | 2019-07-06 08:59:00      | 113095465           |

I want to be able to execute this kind of SQL request using GraphQL:

SELECT * FROM tablename WHERE datetime <= "2019-07-06 09:00:00" AND DATE_ADD(datetime, INTERVAL duration / 1000 SECOND) >= "2019-07-06 08:59:00";

Using a graphql query like : (of course the dates would be in Python DateTime Format)

{  allTable(startDate: "2019-07-06 08:59:00", endDate: "2019-07-06 09:00:00") {    edges {      node {        id        name      }    }  }}

Like this is also fine as long as it works :

{  allTable(timeRange: "{'start':'2019-07-06 08:59:00', 'end': '2019-07-06 09:00:00'}") {    edges {      node {        id        name      }    }  }}

Code

models.py

from django.db import modelsclass TableName(models.Model):    name = models.CharField()    datetime = models.DateTimeField()    duration = models.BigIntegerField()    class Meta:        managed = False        db_table = 'tablename'

schema.py

from graphene import relay, ObjectTypefrom graphene_django import DjangoObjectTypefrom graphene_django.filter import DjangoFilterConnectionFieldimport django_filtersfrom .models import TableNamefrom .fieldList import fields_tableclass TableFilter(django_filters.FilterSet):    class Meta:        model = TableName        fields = fields_tableclass TableType(DjangoObjectType):    class Meta:        model = TableName        filterset_class = TableFilter        interfaces = (relay.Node,)class Query(ObjectType):    table = relay.Node.Field(TableType)    all_Table = DjangoFilterConnectionField(TableType)

I already managed to add custom filter on field and get this filter in GraphQL :

class TableFilter(django_filters.FilterSet):    yolo = django_filters.NumberFilter(field_name="duration", lookup_expr='gt')    ...

But I don't know how to add this type of custom filter.

So far I have seen those documentations: django_filters documentation, Graphene documentation and Django documentation about querysets but couldn't understand everything and could not find an example that match what I need :/

Thanks for taking the time to help :)

Solution(not optimized)

I ended up using this to get what I want but it's not optimized since I can't get all the filters provided by the DjangoFilterConnectionField.

If you have a better solution I will gladly take it since pagination and filters are nice !

schema.py

from graphene import relay, ObjectType, Listfrom graphene_django import DjangoObjectTypefrom graphene_django.filter import DjangoFilterConnectionFieldimport django_filtersimport graphenefrom .models import TableNamefrom .fieldList import fields_tableclass TableFilter(django_filters.FilterSet):    class Meta:        model = TableName        fields = fields_tableclass TableType(DjangoObjectType):    class Meta:        model = TableName        filterset_class = TableFilter        interfaces = (relay.Node,)class Query(ObjectType):    table = relay.Node.Field(TableType)    all_Table = DjangoFilterConnectionField(TableType)    table_range = List(TableType, startDate=graphene.Argument(        graphene.DateTime, required=True), endDate=graphene.Argument(graphene.DateTime, required=True))    def resolve_trace_range(root, info, startDate, endDate):        return TableType.objects.raw("""        SELECT * FROM tablename WHERE        datetime <= '{}'        AND DATE_ADD(datetime, INTERVAL duration / 1000 SECOND) >= '{}';""".format(str(startDate), str(endDate)))

This allows me to do requests like :

{  tableRange(startDate: "2019-08-19T08:31:24.315Z", endDate: "2019-08-19T09:31:24.315Z") {      id      flow      datetime      duration  }}

Note that the DateTime is formatted using ISO-8601.In javascript you can get it using :

now = new Date().toISOString();console.log(now); // Output: 2019-08-19T09:34:19.075Z

Viewing all articles
Browse latest Browse all 13951

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>