将GraphQL API集成到Django应用程序中
GraphQL是一种开源的查询语言,用于在客户端和服务器之间进行数据通信。正如GraphQL文档中所解释的那样,"GraphQL是一种用于API的查询语言,也是一种用于用你现有的数据完成这些查询的运行时间......"
简介
GraphQL由Facebook在2012年创建,为应用程序接口(API)提供了一个运行环境,它易于使用,速度快,对开发者友好。随着时间的推移,GraphQL已经被微软、GitHub、Shopify、亚马逊等公司广泛使用。
GraphQL最突出的属性是,它只需一个请求就能从多个来源返回所请求的数据,这使得它比RESTAPI更受欢迎,而RESTAPI是另一种选择。
从本质上讲,客户端可以在响应中只请求他们需要的数据,这意味着你可以完全控制数据结构,并且在一个请求中,你可以访问大量的服务。GraphQL有很多优点,但是,GraphQL的特点不在本教程的范围之内。
在本教程中,我们的重点是将GraphQL API集成到Django项目中,并有效地使用它来查询数据。
前提条件
要继续学习本教程,你应该具备以下条件。
- 有[Python]的基本知识。
- 对[Django]有良好的理解。
项目设置
我们将创建一个电子商务目录项目。让我们首先在终端为这个项目创建一个目录。
在你的终端上添加以下内容。
mkdir ecommerce
cd ecommerce
设置一个虚拟环境
我们将为这个项目设置一个虚拟环境。虚拟环境有助于安装软件包,通过为不同的项目创建隔离的Python虚拟环境来保持不同项目所需的软件包。
为了创建一个虚拟环境,我们首先安装virtualenv 。
在你的终端上运行以下命令。
pip install virtualenv
virtualenv env
让我们激活我们的虚拟环境。
- Mac OS / Linux。
source env/bin/activate
- Windows。
env\Scripts\activate
让我们继续设置我们的Django依赖性。
pip install django
一旦我们安装了Django,我们将分别创建我们的电子商务项目和应用程序。
django-admin startproject ecommerce
cd ecommerce
django-admin startapp products
现在,我们将进入我们的代码编辑器。在你的代码编辑器中打开项目,在你的项目settings.py文件中,通过注册你的应用程序。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'products',
]
创建模型
下一步,我们将在products/models.py文件中创建我们的产品应用模型。
from django.db import models
# Create your models here.
class Category(models.Model):
title = models.CharField(max_length=255)
class Meta:
verbose_name_plural = 'Categories'
def __str__(self):
return self.title
class Book(models.Model):
title = models.CharField(max_length=150)
author = models.CharField(max_length=100, default='John Doe')
isbn = models.CharField(max_length=13)
pages = models.IntegerField()
price = models.IntegerField()
quantity = models.IntegerField()
description = models.TextField()
status = models.BooleanField()
date_created = models.DateField(auto_now_add=True)
class Meta:
ordering = ['-date_created']
def __str__(self):
return self.title
class Grocery(models.Model):
product_tag = models.CharField(max_length=10)
name = models.CharField(max_length=100)
category = models.ForeignKey(Category, related_name='grocery', on_delete=models.CASCADE)
price = models.IntegerField()
quantity = models.IntegerField()
imageurl = models.URLField()
status = models.BooleanField()
date_created = models.DateField(auto_now_add=True)
class Meta:
ordering = ['-date_created']
def __str__(self):
return self.name
因此,让我们讨论一下我们在上面的代码中到底做了什么。
- 我们创建了三个模型类,Category、Book和Grocery。
- 我们为模型类添加了字段。
- 通过
-date_created,这些模型将根据它们的创建日期来排序。
下一步,让我们在我们的products/admin.py 文件中注册我们的模型。
from django.contrib import admin
from .models import Category, Book, Grocery
# Register your models here.
admin.site.register(Category)
admin.site.register(Book)
admin.site.register(Grocery)
让我们继续在我们的终端运行模型的迁移。通过运行迁移,这些模型被添加到我们的数据库中。
在你的终端运行以下命令。
python manage.py makemigrations
python manage.py migrate
一旦迁移完成,在你的终端中运行以下命令来启动应用程序。
python manage.py runserver
在你的终端中点击链接[http://127.0.0.1:8000/](http://127.0.0.1:8000/) 。如果应用程序显示在你的浏览器上,那么你就走上了正轨。
将GraphQL整合到我们的项目中
我们将把GraphQL整合到我们的Django项目中。首先,让我们安装一个名为Graphene-Django的软件包。
在你的终端上运行。
pip install graphene-django
下一步,将 graphene_django到INSTALLED_APPS 在你的settings.py 文件中。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'products',
'graphene_django',
]
将GraphQL添加到URL中
在使用GraphQL时,客户端可以访问的唯一端点/API是**/graphql**。这是唯一的端点,客户可以通过它来请求和改变数据。因此,与REST相比,我们需要管理的端点较少。
要在我们的URL中添加一个GraphQL视图,在ecommerce/urls.py 文件中。
添加以下内容。
from django.contrib import admin
from django.urls import path
from graphene_django.views import GraphQLView
from products.schema import schema
urlpatterns = [
path('admin/', admin.site.urls),
path("graphql", GraphQLView.as_view(graphiql=True, schema=schema)),
]
该URL包含我们的端点,我们的GraphQL通信将在这里进行。我们导入了GraphQLView ,这是一个由graphene_django 提供的独特视图,当Graphql url被调用时,它将被执行。
然后,我们添加了一个名为graphql的URL。然后,我们设置 graphiql=True这将使我们能够使用graphiql。
创建一个模式
GraphQL是一种查询语言,有一个强大的类型系统,可以用来定义API的数据结构。GraphQL模式被用来表示这些信息。
模式是客户端和服务器之间的契约,描述了客户端如何获得对数据库的访问。
你需要添加一个模式、对象类型和一个接收GraphQL查询的视图函数,以便能够在你的Web应用程序中执行GraphQL查询。
让我们来定义我们的模式,在products/ 目录中,我们将创建一个名为schema.py的文件并添加以下内容。
import graphene
from graphene_django import DjangoObjectType
from .models import Category, Book, Grocery
class CategoryType(DjangoObjectType):
class Meta:
model = Category
fields = ('id','title')
class BookType(DjangoObjectType):
class Meta:
model = Books
fields = (
'id',
'title',
'author',
'isbn',
'pages',
'price',
'quantity',
'description',
'imageurl',
'status',
'date_created',
)
class GroceryType(DjangoObjectType):
class Meta:
model = Grocery
fields = (
'product_tag',
'name',
'category',
'price',
'quantity',
'imageurl',
'status',
'date_created',
)
class Query(graphene.ObjectType):
categories = graphene.List(CategoryType)
books = graphene.List(BookType)
groceries = graphene.List(GroceryType)
def resolve_books(root, info, **kwargs):
# Querying a list
return Book.objects.all()
def resolve_categories(root, info, **kwargs):
# Querying a list
return Category.objects.all()
def resolve_groceries(root, info, **kwargs):
# Querying a list
return Grocery.objects.all()
schema = graphene.Schema(query=Query)
在上面的代码中。
- 我们为我们的三个模型(Category, Book, and Grocery)创建了一个模式。
- 我们还包括
DjangoObjectType:它使用 GraphQL 来显示模型上的所有字段。 class Query继承自*'graphene.ObjectType'*,为我们的Graphql查询提供设置。resolve_categories, books, groceries术语:用于打开类别、书籍、杂货查询集。这些方法接受两个参数(root和info)。graphene.Schema检索:这个查询从我们的类型(数据库)中带来数据。
测试我们的GraphQL API
接下来,我们将测试我们的API,以确保它成功运行。要做到这一点,让我们简单地运行python manage.py runserver 。
让我们检查一下我们的URLhttp://120.0.0.1:8000/graphql。
让我们尝试一些功能来查询我们数据库中的数据。我们将通过使用GraphQL预览来做到这一点,它是导航栏左上方的播放按钮。
{
books{
id
title
author
isbn
pages
price
quantity
description
status
}
}
我们的数据是空的,因为我们没有向数据库添加任何数据。我们不能忘记的一个重要步骤是创建一个管理用户。让我们通过在终端上运行以下几行代码来简要地做这件事。
python manage.py createsuperuser
添加用户名和密码。超级用户成功创建,现在你可以使用http://127.0.0.1:8000/admin/ ,在你的浏览器上运行管理网站。
你可以向任何一个模型中添加数据。
添加突变
在GraphQL中,突变是在添加、更新和删除数据时使用的。它执行的功能与REST API中的POST、DELETE和PUT方法类似。
在你的schema.py文件中添加以下几行代码。
class UpdateCategory(graphene.Mutation):
class Arguments:
# Mutation to update a category
title = graphene.String(required=True)
id = graphene.ID()
category = graphene.Field(CategoryType)
@classmethod
def mutate(cls, root, info, title, id):
category = Category.objects.get(pk=id)
category.title = title
category.save()
return UpdateCategory(category=category)
class CreateCategory(graphene.Mutation):
class Arguments:
# Mutation to create a category
title = graphene.String(required=True)
# Class attributes define the response of the mutation
category = graphene.Field(CategoryType)
@classmethod
def mutate(cls, root, info, title):
category = Category()
category.title = title
category.save()
return CreateCategory(category=category)
class BookInput(graphene.InputObjectType):
title = graphene.String()
author = graphene.String()
pages = graphene.Int()
price = graphene.Int()
quantity = graphene.Int()
description = graphene.String()
status = graphene.String()
class CreateBook(graphene.Mutation):
class Arguments:
input = BookInput(required=True)
book = graphene.Field(BookType)
@classmethod
def mutate(cls, root, info, input):
book = Book()
book.title = input.title
book.author = input.author
book.pages = input.pages
book.price = input.price
book.quantity = input.quantity
book.description = input.description
book.status = input.status
book.save()
return CreateBook(book=book)
class UpdateBook(graphene.Mutation):
class Arguments:
input = BookInput(required=True)
id = graphene.ID()
book = graphene.Field(BookType)
@classmethod
def mutate(cls, root, info, input, id):
book = Product.objects.get(pk=id)
book.name = input.name
book.description = input.description
book.price = decimal.Decimal(input.price)
book.quantity = input.quantity
book.save()
return UpdateBook(book=book)
class Mutation(graphene.ObjectType):
update_category = UpdateCategory.Field()
create_category = CreateCategory.Field()
create_book = CreateBook.Field()
update_book = UpdateBook.Field()
schema = graphene.Schema(query=Query, mutation=Mutation)
- 我们创建了类来添加和更新数据到我们的模型。
- 'class argument'允许我们定义一个参数来保存数据到数据库。
- 'class Mutation'定义了我们的突变,并发送参数,如更新和创建数据到模型中。
- 最后,我们通过向模式构造器添加突变来更新我们的模式。
接下来,我们继续测试我们的突变和查询。让我们创建一个新的类别。
把下面的突变粘贴在左边,然后点击播放按钮。
mutation {
create_category:createCategory(title :"Plastic") {
category {
id,
title,
}
}
}
mutation {
create_book: createBook(input: {title:"Imagine this",author: "Shola", pages: 12, price: 1200, quantity: 4, description:"a brief description", status: "True"}){
book {
id,
title,
author,
pages,
price,
quantity,
description,
status
}
}
}
成功地添加到我们的数据库中!🎉
结语
使用Graphene-Django包,我们能够在本教程中把GraphQL纳入Django。
如果实施得当,Django中的GraphQL将产生一个极具可扩展性和通用性的应用程序。然而,我们并没有使用graphene包的所有功能。
本教程提供了一个关于GraphQL和Django如何整合的偷窥。GraphQL可以用来为你的Django应用程序添加各种额外的功能。
如果你正在开始使用GraphQL和Django,我希望这个教程能对你有所帮助!