Lección 5: Hola DRF
Django REST Framework dispone de 2 componentes propios para la gestión de la base de datos.
- Serializadores: Convierten instancias de modelos (consultas a la base de datos) en formato JSON (serializar), o viceversa (deserializar).
- ViewSets: Similares a las Views (Vistas) de Django, salvo que automatizan las respuestas, verbos (GET, POST…), los modelos que se utilizarán y como se serializará la información resultante (Serializadores).
Vamos a crear un modelo, o tabla en la base de datos, para gestionar los libros.
Primero creamos un test para verificar que se crean correctamente.
# tests/libros/test_create_model.py
import pytest
from app.libros.models import Libros
@pytest.mark.django_db
def test_libros_model():
## Given
# Creamos un nuevo libro en la base de datos
libro = Libros(
title="La fundación",
genre="Ciencia ficción",
year="1951",
author="Isaac Asimov",
)
libro.save()
## When
## Then
assert libro.title == "La fundación"
assert libro.genre == "Ciencia ficción"
assert libro.year == "1951"
assert libro.author == "Isaac Asimov"
assert libro.created_at
assert libro.updated_at
assert str(libro) == libro.title
Lo ejecutamos.
pytest
Por supuesto, nos dirá que no pasa. El modelo no existe. Vamos a definirlo.
# app/libros/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class Libros(models.Model):
title = models.CharField(max_length=255)
genre = models.CharField(max_length=255)
year = models.CharField(max_length=4)
author = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ("-created_at",)
verbose_name = "Libro"
verbose_name_plural = "Libros"
def __str__(self):
return self.title
No recomiendo utilizar uuid
o un bigint
como Id en un modelo o como clave primaria en una base de datos. Cuando la información en una base de datos crece aumenta considerablemente su peso, llegado hasta ocupar hasta un 20% de su capacidad en claves. Podéis leer más al respecto en un fantástico artículo de Shekhar Gulati.
Preparamos la migración.
python3 manage.py makemigrations
La ejecutamos de nuevo.
python3 manage.py migrate
Y probamos el test.
pytest
Pasará sin problemas.
Ahora vamos a definir el serializador para transformar los resultados de la base de datos (models) a JSON. Como siempre, empezamos por el test.
# tests/libros/test_serializers.py
from app.libros.serializers import LibroSerializer
def test_valid_libro_serializer():
valid_serializer_data = {
"title": "Raising Arizona",
"genre": "comedy",
"year": "1987",
"author": "Ray Bradbury",
}
serializer = LibroSerializer(data=valid_serializer_data)
assert serializer.is_valid()
assert serializer.validated_data == valid_serializer_data
assert serializer.data == valid_serializer_data
assert serializer.errors == {}
def test_invalid_libro_serializer():
invalid_serializer_data = {
"title": "Soy Leyenda",
"author": "Richard Matheson",
}
serializer = LibroSerializer(data=invalid_serializer_data)
assert not serializer.is_valid()
assert serializer.validated_data == {}
assert serializer.data == invalid_serializer_data
assert serializer.errors == {
"year": ["This field is required."],
"genre": ["This field is required."],
}
Nos fallará, por supuesto. No hemos realizado el serializador.
pytest
Gracias a adelantarnos en el test ya sabemos como debe estar estructurado.
Creamos el serializador.
# app/libros/serializers.py
from rest_framework import serializers
from .models import Libros
class LibroSerializer(serializers.ModelSerializer):
class Meta:
model = Libros
fields = "__all__"
read_only_fields = (
"id",
"created_at",
"updated_at",
)
Le indicamos que use todos los campos, y que solo pueda leer id
, created_at
y updated_at
.
Ahora ya podemos pasar el test. Si solo deseas comprobar el último que hemos realizado, puedes concretar con el argumento -k
y el nombre del archivo evitando el prefijo test_.
pytest -k serializers
Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.
¿Me invitas a un café? ☕
Puedes hacerlo usando el terminal.
ssh customer@andros.dev -p 5555
Comentarios
Nuevo comentario
Nueva replica {{ formatEllipsisAuthor(replyComment.author) }}
Escribe el primer comentario
{{ comments.length }} comentarios