En este tutorial vas a aprender a desarrollar una aplicación web Backend en Django que permite exponer una API usando GraphQL como lenguaje de consultas.
Requerimientos
- Conocimintos Básicos en Django
- Conocimientos Básicos en GraphQL
Creación de Proyecto
Primero crearemos un proyecto en Django:
mkdir django-graphql
cd django-graphql
Luego crearemos un entorno virtual
python -m venv venv
code .
Luego isntalaremos el paquete Django y crearemos un proyecto nuevo:
pip install django
Crearemos un proyecto con django:
django-admin startproject core .
y luego una aplicación llamada books
:
python manage.py startapp books
Luego en core/settings.py
puedes añadir la apps books:
INSTALLED_APPS = [
...
"books"
]
Creación de Modelo
Luego para crear un modelo para la base de datos, ve en books/models.py
:
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=255)
desc = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
Luego vamos a ejecutar las migraciones del ORM para que genere las tablas de la base de datos:
python manage.py makemigrations
python manage.py migrate
Luego vamos a añadir el modelo de books
a books/admin.py
:
from django.contrib import admin
from .models import Book
# Register your models here.
admin.site.register(Book)
crea un superusuario
Luego crea un usuario administrador con:
python manage.py createsuperuser
Hasta aqui si ejecutan:
python manage.py runserver
Y luego vas a la dirección http://localhost:8000/admin
podras usar tu usuario y crear datos para libros.
Crea algunos datos de Libros para que luego podamos consultarlos con la API de GraphQL
Así que lo siguiente es crear una API para consumir estos datos desde aplicaciones cliente, en nuestro caso estaremos utilizando una API de GraphqQL creada con Graphene.
instalación de GraphQL con Graphene
Primero instalaremos GraphQL en nuestro proyecto de Django usando Graphene
pip install graphene-django
luego añade lo siguient en core/settings.py
:
INSTALLED_APPS = [
...
"django.contrib.staticfiles", # Required for GraphiQL
"graphene_django"
]
Luego lo siguiente que tenemos que hacer, es decir en donde esta nuestro proyecto de , una forma de decir donde esta el schema es añadiendo esto en core/settings.py
GRAPHENE = {
"SCHEMA": "core.schema.schema"
}
pero en lo personal prefiero añadirlo de esta otra forma:
Prmero crea un schema en core/schema.py
con el siguiente código:
import graphene
class Query(graphene.ObjectType):
hello = graphene.String(default_value="Hi!")
schema = graphene.Schema(query=Query)
luego en core/urls.py
from django.contrib import admin
from django.urls import path
from graphene_django.views import GraphQLView
from core.schema import schema
urlpatterns = [
path("admin/", admin.site.urls),
path("graphql", GraphQLView.as_view(graphiql=True, schema=schema)),
]
Luego pudes consular esto desde http://localhost:8000
{
hello
}
Lista de Libros
Ahora vamos a crear una consulta mas extensa que permita ver una lista de libros, primero vamos a definir un modelo de como lucen los libros, añade esto en core/schema.py
import graphene
from graphene_django import DjangoObjectType
from books.models import Book
class BookType(DjangoObjectType):
class Meta:
model = Book
fields = ("id", "title", "desc")
....
schema = graphene.Schema(query=Query)
luego añadiremos un Query de GraphQL, junto con su resolver para que pueda devolver datos al cliente:
class Query(graphene.ObjectType):
...
books = graphene.List(BookType)
def resolve_books(self, info):
return Book.objects.all()
Ahora puedes obtener una lista de libros consultado:
{
books {
id
title
description
}
}
Obtener un unico libro
Ahora vamos a crear la consulta para obtener un unico Libro.
en core/schema.py
, actualiza lo siguiente:
class Query(graphene.ObjectType):
book = graphene.Field(BookType, id=graphene.Int())
...
def resolve_book(self, info, id):
return Book.objects.get(pk=id)
Luego podras consultar usando:
{
book(id: 1) {
id
title
desc
}
}
Mutaciones
Ahora vamos a intentar añadir datos usando la API de GraphQL, para esto usaremos las mutaciones.
Primero añade una nueva clase llamada
Mutation en core/schema.py
:
class Query():
....
class CreateBookMutation(graphene.Mutation):
class Arguments:
title = graphene.String()
description = graphene.String()
book = graphene.Field(BookType)
def mutate(self, info, title, description):
book = Book(title=title, description=description)
book.save()
return CreateBookMutation(book=book)
schema = graphene.Schema(query=Query, mutation=Mutation)
mutation {
createBook(title:"my second book", desc: "some description") {
id
title
desc
}
}
Luego para el delete
class DeleteBook(graphene.Mutation):
class Arguments:
id = graphene.Int(required=True)
message = graphene.String()
def mutate(self, info, id):
book = Book.objects.get(pk=id)
book.delete()
return DeleteBook(message="Book deleted")
class Mutation(graphene.ObjectType):
create_book = graphene.Field(BookType, title=graphene.String(), desc=graphene.String())
deleteBook = DeleteBook.Field()
update_book = graphene.Field(BookType, id=graphene.Int(), title=graphene.String(), desc=graphene.String())
mutation {
deleteBook(id: 3) {
message
}
}
Y finalmente para el update
class UpdateBook(graphene.Mutation):
class Arguments:
id = graphene.Int(required=True)
title = graphene.String()
description = graphene.String()
book = graphene.Field(BookType)
def mutate(self, info, id, title, description):
book = Book.objects.get(pk=id)
book.title = title
book.description = description
book.save()
return UpdateBook(book=book)
class Mutation(graphene.ObjectType):
...
udpate_book = UpdateBook.Field()
mutation {
updateBook(id: 2, title: "my new book", desc:"some new book") {
id
title
desc
}
}