你好,
我正在使用 Graphene Django 和 Graphene Relay 以及 Python 3.7。我正在尝试使用 Django 过滤器为 GraphQL 中的请求创建自定义过滤器。
我的桌子是这样的:
| 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 |
我希望能够使用 GraphQL 执行这种 SQL 请求:
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";
使用像这样的 graphql 查询:(当然日期将采用 Python DateTime 格式)
{
allTable(startDate: "2019-07-06 08:59:00", endDate: "2019-07-06 09:00:00") {
edges {
node {
id
name
}
}
}
}
这样只要能用就可以了:
{
allTable(timeRange: "{'start':'2019-07-06 08:59:00', 'end': '2019-07-06 09:00:00'}") {
edges {
node {
id
name
}
}
}
}
models.py
from django.db import models
class 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, ObjectType
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
import django_filters
from .models import TableName
from .fieldList import fields_table
class TableFilter(django_filters.FilterSet):
class Meta:
model = TableName
fields = fields_table
class TableType(DjangoObjectType):
class Meta:
model = TableName
filterset_class = TableFilter
interfaces = (relay.Node,)
class Query(ObjectType):
table = relay.Node.Field(TableType)
all_Table = DjangoFilterConnectionField(TableType)
我已经设法在字段上添加自定义过滤器并在 GraphQL 中获取此过滤器:
class TableFilter(django_filters.FilterSet):
yolo = django_filters.NumberFilter(field_name="duration", lookup_expr='gt')
...
但是我不知道如何添加这种类型的自定义过滤器。
到目前为止,我已经看过这些文档:django_filters文档,Graphene文档和有关查询集的Django文档,但无法理解所有内容,也找不到符合我需要的示例:/
感谢您抽出时间来帮助:)
我最终使用它来获得我想要的东西,但它没有优化,因为我无法获得
DjangoFilterConnectionField
提供的所有过滤器。
如果您有更好的解决方案,我很乐意接受,因为分页和过滤器很好!
schema.py
from graphene import relay, ObjectType, List
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
import django_filters
import graphene
from .models import TableName
from .fieldList import fields_table
class TableFilter(django_filters.FilterSet):
class Meta:
model = TableName
fields = fields_table
class 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)))
这允许我执行如下请求:
{
tableRange(startDate: "2019-08-19T08:31:24.315Z", endDate: "2019-08-19T09:31:24.315Z") {
id
flow
datetime
duration
}
}
请注意,日期时间使用 ISO-8601 进行格式化。 在 javascript 中你可以使用 :
来获取它now = new Date().toISOString();
console.log(now);
// Output: 2019-08-19T09:34:19.075Z
您可以像这样创建一个自定义石墨烯对象
class TableFilterInputObjects(graphene.InputObjectType):
start_date = graphene.Date()
end_date = graphene.Date()
然后你就可以像这样简单地使用它了
class Query(ObjectType):
table_range = List(TableType, filter = TableFilterInputObjects(required = True))
def resolve_trace_range(root, info,filter):
filters = Q()
if filter is not None:
if filter.start_date is not None:
filters &=Q(datetime__gte = start_date)
if filter.end_date is not None:
filters &=Q(datetime__lte = end_date)
return TableType.objects.filter(filters).all()