6. Create
The goal will be to create a CRUD of Endpoints (add-read-update-delete) with Book to read and manage it in all the ways we need.
The first goal will be to define an Endpoint to create a new book (POST). We start by creating a new test.
# tests/libros/test_views.py
import pytest
from app.libros.models import Libros
@pytest.mark.django_db
def test_add_libro(client):
# Given
libros = Libros.objects.all()
assert len(libros) == 0
# When
resp = client.post(
"/api/libros/",
{
"title": "El fin de la eternidad",
"genre": "Ciencia Ficción",
"author": "Isaac Asimov",
"year": "1955",
},
content_type="application/json"
)
# Then
assert resp.status_code == 201
assert resp.data["title"] == "El fin de la eternidad"
libros = Libros.objects.all()
assert len(libros) == 1
When you run it, it will fail, as always (for more information you can see my explanation of TDD).
We update the view.
# app/libros/views.py
from django.http import JsonResponse
from rest_framework.views import APIView # new
from rest_framework.response import Response # new
from rest_framework import status # new
from .serializers import LibroSerializer # new
def ping(request):
data = {"ping": "pong!"}
return JsonResponse(data)
# new from here
class LibrosList(APIView):
def post(self, request):
serializer = LibroSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# new up to here
To separate the urls of the different applications, we are going to create a route in the urls.py of libros.
# app/libros/urls.py
from django.urls import path
from app.libros.views import ping, LibrosList
urlpatterns = [
path("ping/", ping, name="ping"),
path("api/libros/", LibrosList.as_view()),
]
Meanwhile, inside proyecto/urls.py we will call the routes of all the applications. In this case only admin and libros.
# proyecto/urls.py
from django.contrib import admin
from django.urls import path, include # new
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("app.libros.urls")), # new
]
Now the test will run.
pytest -k views
Another option is to use an HTTP client like curl or HTTPie.
# curl
curl -XPOST -H "Content-type: application/json" -d '{
"title": "El fin de la eternidad",
"genre": "Ciencia Ficción",
"author": "Isaac Asimov",
"year": 1955
}' http://localhost:8000/api/libros/
# HTTPie
http --json \
POST http://localhost:8000/api/libros/ \
title="El fin de la eternidad" \
genre="Ciencia Ficción" \
author="Isaac Asimov" \
year=1955
It will return.
HTTP/1.1 201 Created
Allow: POST, OPTIONS
Content-Length: 192
Content-Type: application/json
Date: Sun, 11 Jul 2021 21:30:04 GMT
Referrer-Policy: same-origin
Server: WSGIServer/0.2 CPython/3.9.2
Vary: Accept, Cookie
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
{
"author": "Isaac Asimov",
"created_at": "2021-07-11T21:30:04.088124Z",
"genre": "Ciencia Ficción",
"id": 1,
"title": "El fin de la eternidad",
"updated_at": "2021-07-11T21:30:04.088160Z",
"year": "1955"
}
This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.
Building SPAs with Django and HTML Over the Wire: Learn to build real-time single page applications with Python
The HTML over WebSockets approach simplifies single-page application (SPA) development and lets you bypass learning a JavaScript rendering framework such as React, Vue, or Angular, moving the logic to Python. This web application development book provides you with all the Django tools you need to simplify your developments with real-time results.
Buy the bookHelp me keep writing
Every coffee gives me a push toward the next article.
Sure, it's on me!
Comments
There are no comments yet.