如何在Django中使用GraphQL
GraphQL是未来的趋势吗?
GraphQL是一种用于API的查询语言,使客户能够准确地从API中提出他们所需要的东西。在这篇文章中,我们将探讨GraphQL以及如何在Django (Python网络框架)中使用它。让我们来参观一下。
安装
$ pip install Django$ pip install graphene-django
设置Django项目
我们需要创建我们的Django项目。
- 一个名为Django的项目
bookstore - 在
bookstore内的一个应用程序,名为books
$ django-admin startproject bookstore
$ cd bookstore
$ django-admin startapp books
settings.py我们需要在我们的Django项目的graphene_django 和bookstore.books中添加INSTALLED_APPS 。
INSTALLED_APPS = [
#...
'django.contrib.staticfiles',
'graphene_django'
'bookstore.books'
]
定义我们的模型
一个模型是关于我们数据的单一的、确定的信息来源。每个模型都映射到一个单一的数据库表。我们将使用一个SQLite数据库,用于在线书店的库存和销售database/bookstore.db
from django.db import models
#...
class Publisher(models.Model):
id = models.AutoField(primary_key=True)
p_name = models.CharField(max_length=40)
city = models.CharField(max_length=20)
zip = models.CharField(max_length=10)
class Meta:
managed = False
db_table = 'Publisher'
class Book(models.Model):
id = models.CharField(max_length=20, primary_key=True)
pub = models.ForeignKey('Publisher', models.DO_NOTHING)
title = models.CharField(max_length=100)
price = models.FloatField()
category = models.CharField(max_length=30, null=True)
quantity = models.IntegerField()
b_format = models.CharField(max_length=40, null=True)
prod_year = models.IntegerField()
filesize = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'Book'
- 在你的Django项目的
urls.py,添加一个graphqlURL。
from django.urls import path
from graphene_django.views import GraphQLView
urlpatterns = [
#...
path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))),
]
CSRF中间件和模板标签提供了易于使用的保护,防止跨站请求伪造。
- 在我们的Django项目设置中定义Graphene的模式位置。
GRAPHENE = { 'SCHEMA': 'bookstore.books.schema'}
为了进行GraphQL查询,我们需要.NET Framework。
- 带有定义对象类型的模式。
- 一个视图,将查询作为输入并返回结果。
模式books/schema.py 应该包括两个名为Query 和Mutation 的类,这些类扩展了你应用程序中的所有模式。
查询
查询是发送到服务器的字符串,被解释和执行,然后它们返回JSON数据给客户端。这里我们有一个查询,它将返回存储在数据库中的所有书籍和出版商的列表。
import graphene
from graphene import ObjectType, Schema, Mutationfrom graphene_django import DjangoObjectType
from bookstore.books.models import Publisher, Book
class PublisherType(DjangoObjectType):
class Meta:
model = Publisher
fields = ("id", "p_name", "city", "zip")
class BookType(DjangoObjectType):
class Meta:
model = Book
fields = ("id", "pub", "title", "price", "category", "quantity", "b_format", "prod_year", "filesize")
class Query(ObjectType):
all_book = graphene.List(BookType)
all_publisher = graphene.List(PublisherType)
解析器
为了响应查询,一个模式需要有所有字段的解析器。解析器是一个函数的集合,它为GraphQL查询生成响应。
#...
@graphene.resolve_only_args
def resolve_all_book(self):
return Book.objects.all()
@graphene.resolve_only_args
def resolve_all_publisher(self):
return Publisher.objects.all()
变异
大多数关于GraphQL的讨论都集中在数据获取上,但任何完整的数据平台都需要一种方法来修改服务器端的数据。突变查询修改数据存储中的数据并返回一个值。
class CreatePublisher(Mutation):
id = graphene.String()
p_name = graphene.String()
city = graphene.String()
zip = graphene.String()
class Arguments:
id = graphene.NonNull(graphene.Int)
p_name = graphene.String()
city = graphene.String()
zip = graphene.String()
def mutate(self, info, id, p_name, city, zip):
publisher = Publisher(id=id, p_name=p_name, city=city, zip=zip)
publisher.save()
return CreatePublisher(id = publisher.id,
p_name = publisher.p_name,
city = publisher.city,
zip = publisher.zip,
)
class Mutation(graphene.ObjectType):
create_publisher = CreatePublisher.Field()
GraphQL vs. REST API
GraphQL和REST API的主要区别在于,GraphQL是一种规范,一种查询语言,而REST是基于网络的软件的架构概念。
一个REST请求是由endpoint 、HTTP method 、Header 、Body 。对于调用REST API,我们一般使用HTTP方法,如POST、GET、PUT和DELETE ,而另一方面,GraphQL使用不同的方法,称为查询 和变异。
总结
GraphQL很好,它是强类型的,基于模式类型和描述的自我记录,并与代码生成器工具集成以减少开发时间。