Lección 7: Detalles

Ahora nos encargaremos de ver los detalles de un libro en concreto (GET).

Creamos los test que podamos comprobar si nos devuelve los datos de un libro en concreto y otro para comprobar que nos devuelve un error si no existe. Añadimos a tests/libros/test_views.py ambos test.

# 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): # nuevo

    # 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_libro_incorrect_id(client): # nuevo

    # When
    resp = client.get(f"/api/libros/-1/")

    # Then
    assert resp.status_code == 404

Es el momento de definir la vista.

# 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 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): # nuevo

    def get(self, request, pk):
        libro = Libros.objects.filter(pk=pk).first()
        serializer = LibroSerializer(libro)
        if libro:
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_404_NOT_FOUND)

Y registrar su url. Le indicamos que necesitará un número después de libros. Por ejemplo api/libros/23/ .

# app/libros/urls.py

from django.urls import path
from app.libros.views import *

urlpatterns = [
    path("ping/", ping, name="ping"),
    path("api/libros/", LibrosList.as_view()),
    path("api/libros/<int:pk>/", LibrosDetails.as_view()), # nuevo
]

El test ya pasará.

Además puedes comprobar con un cliente HTTP que se recibe. (No olvides levantar el servidor y crear un libro)

# curl
curl http://localhost:8000/api/libros/1/

# HTTPie
http GET http://localhost:8000/api/libros/1/
Allow: GET, HEAD, OPTIONS
Content-Length: 192
Content-Type: application/json
Date: Mon, 12 Jul 2021 21:00:51 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"
}

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Me ayudas?

Comprame un café
Pulsa sobre la imagen

No te sientas obligado a realizar una donación, pero cada aportación mantiene el sitio en activo logrando que continúe existiendo y sea accesible para otras personas. Además me motiva a crear nuevo contenido.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario