14
ORM en Django
Una vez entendiendo la manera de trabajar de django con respecto a los templates, views y urls, nos vemos en la necesidad de entender el trabajo que involucra la parte de los datos, la capa del modelado, y en django, se trabaja bajo la lógica del ORM.
Si aún no comprendes que es ORM en si, te aconsejaría leer este artículo (click acá) antes de seguir con esta lectura.
Para entender como se trabajan las ORM en Django crearemos un ejemplo con tres clases: Author, Book y Reader.
En nuestro archivo models.py de nuestra app books, tenemos el siguiente contenido:
from django.db import models
class Author(models.Model):
first_name = models.CharField(verbose_name="Nombres", max_length=50)
last_name = models.CharField(verbose_name="Apellidos", max_length=50)
def __str__(self):
return self.first_name + " " + self.last_name
class Book(models.Model):
name = models.CharField(verbose_name="Nombre del libro", max_length=50)
author = models.ForeignKey(Author, related_name="books",verbose_name="Autor", on_delete=models.CASCADE)
price = models.FloatField(verbose_name="Precio")
preview = models.FileField(upload_to="books/", verbose_name="Adjunto del libro")
def __str__(self):
return self.name
class Reader(models.Model):
first_name = models.CharField(verbose_name="Nombres", max_length=50)
last_name = models.CharField(verbose_name="Apellidos", max_length=50)
readed_books = models.ManyToManyField(Book, related_name="readers")
def __str__(self):
return self.first_name + " " + self.last_name
En este punto, tenemos varias cosas que ya manejamos, pero procederé para refrescar:
- models.CharField, models.FloatField, models.FileField : funciones que se encargan de asignar un tipo de dato a un atributo de la clase (que se convertirá en una columna en la base de datos), la mayoría de ellos reciben parámetros como verbose_name, max_length, upload_to, que se encargan de cambiar las características de este atributo.
- models.ForeignKey, models.ManyToMany: en ORM existen varias maneras de relacionar entre las clases: 1 a 1, 1 a muchos y de muchos a muchos, cuando se ocupan estas funciones solo escribimos la relación que tendrán, comúnmente se agrega un related_name, que será clave para las llamadas en ambos sentido.
Como la base de datos estaba con datos, se limpió y se hizo make migrations y migrate.
Una vez hecho esto, procederemos a trabajar con las ORM, todo esto lo haremos en la shell de django:
Tenemos dos maneras de crear objetos, la primera manera, se crea el objeto y luego se guarda en la base de datos, y la otra manera es crear el objeto en la base de datos directamente.
>>> from books.models import Author
>>> new_author = Author(first_name="Axel",last_name="García")
>>> new_author.save() # Primera manera
>>> Author.objects.create(first_name="Fulano",last_name="Del Rosario") # segunda manera
<Author: Fulano Del Rosario>
Para la creación de los primeros libros, usaremos la variable new_author que actualmente guarda el autor Axel García.
>>> from books.models import Book
>>> new_book = Book(name="Primero", author=new_author, price=120, preview="google.com")
>>> new_book.save()
>>> new_book2 = Book(name="Segundo", author=new_author, price=120, preview="google.com")
>>> new_book2.save()
Y por último, agregaremos los primeros lectores.
>>> from books.models import Reader
>>> new_reader = Reader(first_name="Santiago", last_name="Matamoros")
>>> new_reader.save()
En el caso de los libros, rellenar el autor del libro fue fácil porque solo debes de pasar el objeto, en caso de las relaciones de muchos a muchos, debes tratarlos como una colección, para este ejemplo, se agregaran como "readed_books", los dos libros creados, de la siguiente manera:
>>> new_reader.readed_books.add(new_book)
>>> new_reader.readed_books.add(new_book2)
Para confirmar que esto se realice exitosamente, podemos inspeccionar lo que tenemos en readed_books, pero, como dije, debemos de tratarlo como una colección:
>>> new_reader.readed_books.all()
<QuerySet [<Book: Primero>, <Book: Segundo>]>
De esta manera podemos trabajar las relacionas con las ORM, este ejemplo es algo rápido, así que cualquier comentario para mejorarlo o agregar más cosas que sean necesarias, estoy pendiente.
Fuentes:
14