10. Update
It is time to update a book.
We add the appropriate tests.
- It updates correctly.
- It fails if we try to update a book that does not exist.
- It fails if we try to update a book with incorrect JSON.
# tests/libros/test_views.py
import pytest
from app.libros.models import Libros
@pytest.mark.django_db
def test_add_book(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
@pytest.mark.django_db
def test_get_single_book(client):
# Given
libro = Libros.objects.create(
title="El fin de la eternidad",
genre="Ciencia Ficción",
author="Isaac Asimov",
year="1955",
)
# When
resp = client.get(f"/api/libros/{libro.id}/")
# Then
assert resp.status_code == 200
assert resp.data["title"] == "El fin de la eternidad"
@pytest.mark.django_db
def test_get_single_book_incorrect_id(client):
# When
resp = client.get(f"/api/libros/-1/")
# Then
assert resp.status_code == 404
@pytest.mark.django_db
def test_get_all_books(client, faker):
# Given
def create_random_book():
return Libros.objects.create(
title=faker.name(),
genre=faker.job(),
author=faker.name_nonbinary(),
year=faker.year(),
)
libro_1 = create_random_book()
libro_2 = create_random_book()
# When
resp = client.get(f"/api/libros/")
# Then
assert resp.status_code == 200
assert resp.data[0]["title"] == libro_1.title
assert resp.data[1]["title"] == libro_2.title
@pytest.mark.django_db
def test_remove_book(client):
# Given
libro = Libros.objects.create(
title="El fin de la eternidad",
genre="Ciencia Ficción",
author="Isaac Asimov",
year="1955",
)
## Check exist
resp_detail = client.get(f"/api/libros/{libro.id}/")
assert resp_detail.status_code == 200
assert resp_detail.data["title"] == "El fin de la eternidad"
# When
resp_delete = client.delete(f"/api/libros/{libro.id}/")
resp_list = client.get("/api/libros/")
rest_new_detail = client.get(f"/api/libros/{libro.id}/")
# Then
## Check status delete
assert resp_delete.status_code == 200
## Check return delete
assert resp_delete.data["title"] == "El fin de la eternidad"
## Check status list
assert resp_list.status_code == 200
## Check not item list
assert len(resp_list.data) == 0
## Check not exist detail
assert rest_new_detail.status_code == 404
@pytest.mark.django_db
def test_remove_book_incorrect_id(client):
# Given
libro = Libros.objects.create(
title="El fin de la eternidad",
genre="Ciencia Ficción",
author="Isaac Asimov",
year="1955",
)
# When
resp = client.delete(f"/api/movies/-1/")
# Then
assert resp.status_code == 404
@pytest.mark.django_db
def test_update_book(client): # new
# Given
libro = Libros.objects.create(
title="El fin de la eternidad",
genre="Ciencia Ficción",
author="Isaac Asimov",
year="1955",
)
# When
resp = client.put(
f"/api/libros/{libro.id}/",
{
"title": "Dune",
"genre": "Ciencia Ficción",
"author": "Frank Herbert",
"year": "1965",
},
content_type="application/json"
)
# Then
assert resp.status_code == 200
assert resp.data["title"] == "Dune"
assert resp.data["genre"] == "Ciencia Ficción"
assert resp.data["author"] == "Frank Herbert"
assert resp.data["year"] == "1965"
resp_detail = client.get(f"/api/libros/{libro.id}/")
assert resp_detail.status_code == 200
assert resp_detail.data["title"] == "Dune"
assert resp_detail.data["genre"] == "Ciencia Ficción"
assert resp_detail.data["author"] == "Frank Herbert"
assert resp_detail.data["year"] == "1965"
@pytest.mark.django_db
def test_update_book_incorrect_id(client): # new
resp = client.put(f"/api/libros/-1/")
assert resp.status_code == 404
@pytest.mark.django_db
def test_update_book_invalid_json(client): # new
# Given
libro = Libros.objects.create(
title="El fin de la eternidad",
genre="Ciencia Ficción",
author="Isaac Asimov",
year="1955",
)
# When
resp = client.put(
f"/api/libros/{libro.id}/",
{
"foo": "Dune",
"boo": "Ciencia Ficción",
},
content_type="application/json"
)
# Then
assert resp.status_code == 400
The view will be very simple thanks to the fact that we already have a Serializer and the LibroDetails route.
# app/libros/views.py
from django.http import JsonResponse
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializers import LibroSerializer
from .models import Libros
def ping(request):
data = {"ping": "pong!"}
return JsonResponse(data)
class LibrosList(APIView):
def get(self, request):
libros = Libros.objects.all().order_by('created_at')
serializer = LibroSerializer(libros, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
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)
class LibrosDetails(APIView):
def get(self, request, pk):
libro = Libros.objects.filter(pk=pk).first()
if libro:
serializer = LibroSerializer(libro)
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(status=status.HTTP_404_NOT_FOUND)
def put(self, request, pk): # new
libro = Libros.objects.filter(pk=pk).first()
serializer = LibroSerializer(libro, data=request.data)
if libro and serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk):
libro = Libros.objects.filter(pk=pk).first()
if libro:
serializer = LibroSerializer(libro)
libro.delete()
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(status=status.HTTP_404_NOT_FOUND)
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.