03#Relay和Django Filter-Graphene-Django系统学

222 阅读2分钟

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的朋友指正