Relay和Django Filter
Relay是一个GraphQL的客户端实现。我猜测是为了更好的和Relay配合吧,所以文档又单说了一章。
项目建立
项目创建参照我写的第二篇,其实就是正常的创建Django流程。我这里只讲讲schema定义和客户端使用,只有这两个地方有所区别。
Schema
在cookbook的ingredients里定义一个schema
# cookbook/ingredients/schema.py
from graphene import relay, ObjectType
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from ingredients.models import Category, Ingredient
# Graphene将自动映射到数据库模型的字段
class CategoryNode(DjangoObjectType):
class Meta:
model = Category
filter_fields = ['name', 'ingredients']
interfaces = (relay.Node, ) # 接口采用relay
class IngredientNode(DjangoObjectType):
class Meta:
model = Ingredient
# 通过和Django filter的配合,可以实现更高级的筛选
filter_fields = {
'name': ['exact', 'icontains', 'istartswith'],
'notes': ['exact', 'icontains'],
'category': ['exact'],
'category__name': ['exact'],
}
interfaces = (relay.Node, )
class Query(graphene.ObjectType):
category = relay.Node.Field(CategoryNode)
all_categories = DjangoFilterConnectionField(CategoryNode)
ingredient = relay.Node.Field(IngredientNode)
all_ingredients = DjangoFilterConnectionField(IngredientNode)
补充一点:
代码里用到的高级筛选字段解释:
- istartswith: 不区分大小写从开头匹配
- exact: 精确匹配
- icontains: 不区分大小写的包含匹配
高级筛选可以用到的字段可以参考django文档的query,django filter文档暂时没查到。
执行查询 | Django 文档 | Django (djangoproject.com)
在项目目录下再建立一个schema
import graphene
import ingredients.schema
class Query(ingredients.schema.Query, graphene.ObjectType):
pass
schema = graphene.Schema(query=Query)
更新配置
#cookbook/settings.py
INSTALLED_APPS = [
...
'graphene_django',
'ingredients',
]
# ...
GRAPHENE = {
'SCHEMA': 'cookbook.schema.schema'
}
更新路由
其实和上节讲的一样,我这里再写一次,防止有朋友漏写了。
from django.conf.urls import url, include
from django.contrib import admin
from graphene_django.views import GraphQLView
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^graphql$', GraphQLView.as_view(graphiql=True)),
]
安装Django Filter
pip install django-filter
运行
python manage.py runserver
客户端查询
我们运行一下查询语句
query {
allIngredients {
edges {
node {
id,
name
}
}
}
}
有条件的查询
query {
ingredient(id: "SW5ncmVkaWVudE5vZGU6MQ==") {
name
}
}
多级查询
query {
allCategories {
edges {
node {
name,
ingredients {
edges {
node {
name
}
}
}
}
}
}
}
高级筛选的查询:
query {
allIngredients(name_Icontains: "e", category_Name: "Meat") {
edges {
node {
name
}
}
}
}
结语: 这章讲的不是太好,欢迎熟悉relay的朋友指正