Movatterモバイル変換


[0]ホーム

URL:


  1. Aprende desarrollo web
  2. Módulos de extensión
  3. Programación lado servidor
  4. Framework Web Django (Python)
  5. Tutorial Django Parte 3: Uso de modelos

Esta página ha sido traducida del inglés por la comunidad.Aprende más y únete a la comunidad de MDN Web Docs.

View in EnglishAlways switch to English

Tutorial Django Parte 3: Uso de modelos

Este artículo muestra cómo definir modelos para el sitio web de laBibliotecaLocal. En él se explica lo que es un modelo, cómo se declara, y cuáles son algunos de los principales tipos de campos de un modelo. También veremos, brevemente, cuáles son algunas de las maneras en que puede accederse a los datos del modelo.

Pre-requisitos:Tutorial Django Parte 2: Creación del esqueleto del sitio web.
Objetivo:

Ser capaz de diseñar y crear tus propios modelos, eligiendo de forma apropiada los campos.

Visión general

Las aplicaciones web de Django acceden y administran los datos a través de objetos de Python a los que se hace referencia como modelos. Los modelos definen laestructura de los datos almacenados, incluidos lostipos de campo y los atributos de cada campo, como su tamaño máximo, valores predeterminados, lista de selección de opciones, texto de ayuda para la documentación, texto de etiqueta para formularios, etc. La definición del modelo es independiente de la base de datos subyacente. puede elegir una de entre varias como parte de la configuración de su proyecto. Una vez que haya elegido la base de datos que desea usar, no necesita hablar directamente con ella. Simplemente escriba la estructura de su modelo y algo de código, y Django se encargará de todo el trabajo sucio, al comunicarse con la base de datos por usted.

Este tutorial muestra cómo definir y acceder a los modelos para el ejemplo delsitio web LocalLibrary.

Diseñando los modelos de LocalLibrary

Antes de dar el salto y comenzar a codificar los modelos, vale la pena tomarse unos minutos para pensar qué datos necesitamos almacenar y cuáles serán las relaciones entre los diferentes objetos.

Sabemos que tenemos que almacenar información sobre libros (título, resumen, autor, idioma escrito, categoría, ISBN) y que podríamos tener varias copias disponibles (con id único global, estado de disponibilidad, etc.). Es posible que necesitemos almacenar más información sobre el autor que solo su nombre, y puede haber varios autores con el mismo nombre o nombres similares. Queremos poder ordenar la información según el título del libro, el autor, el idioma escrito y la categoría.

Al diseñar sus modelos, tiene sentido tener modelos separados para cada "objeto" (grupo de información relacionada). En este caso, los objetos obvios son libros, instancias de libros y autores.

También es posible que desee utilizar modelos para representar las opciones de la lista de selección (por ejemplo, como una lista desplegable de opciones), en lugar de codificar las opciones en el sitio web en sí; esto se recomienda cuando no se conocen de antemano todas las opciones posibles o éstas están sujetas a cambios. Los candidatos obvios para las modelos, en este caso, incluyen el género del libro (por ejemplo, ciencia ficción, poesía francesa, etc.) y el idioma (inglés, francés, japonés).

Una vez que hayamos decidido cuáles serán nuestros modelos y sus campos, debemos pensar en la relación que existe entre ellos. Django le permite definir relaciones de uno a uno (OneToOneField), de uno a muchos (ForeignKey) y de muchos a muchos (ManyToManyField).

Con esto en mente, el diagrama de asociación UML a continuación muestra los modelos que definiremos en este caso (como recuadros). Como se mencionó anteriormente, hemos creado modelos para el libro (los detalles genéricos del libro), instancia del libro (estado de copias físicas específicas del libro disponible en el sistema) y autor. También hemos decidido tener un modelo para el género, para que los valores se puedan crear/seleccionar a través de la interfaz admin. Hemos decidido no tener un modelo para elBookInstance:status, en su lugar, hemos especificado directamente, en el código, los valores (LOAN_STATUS) porque no esperamos que cambien. Dentro de cada uno de los cuadros, puede ver el nombre del modelo, los nombres y tipos de campo, y también los métodos y sus tipos de devolución.

El diagrama también muestra las relaciones entre los modelos, incluida sucardinalidad. La cardinalidad expresa la cantidad de instancias (máximo y mínimo) de cada modelo que pueden estar presentes en la relación. Por ejemplo, la línea de conexión entre los cuadros muestra queBook yGenre están relacionados. Los números cercanos al modeloBook muestran que un libro debe tener uno o másGenres (tantos como desee), mientras que los números al otro lado de la línea al lado deGenre muestran que puede tener cero o más libros asociados.

LocalLibrary Model UML

Nota:La siguiente sección proporciona un manual básico que explica cómo se definen y utilizan los modelos. Mientras lo lees, considera cómo construiremos cada uno de los modelos en el diagrama de arriba.

Cartilla del Modelo

Esta sección provee una vista resumida de cómo se define un modelo y algunos de los campos más importantes y argumentos de campo.

Definición de modelo

Los modelos están definidos, normalmente, en el archivomodels.py de la aplicación. Son implementados como subclases dedjango.db.models.Model, y pueden incluir campos, métodos y metadata. El fragmento de código más abajo muestra un modelo "típico", llamadoMyModelName:

python
from django.db import modelsclass MyModelName(models.Model):    """    Una clase típica definiendo un modelo, derivado desde la clase Model.    """    # Campos    my_field_name = models.CharField(max_length=20, help_text="Enter field documentation")    ...    # Metadata    class Meta:        ordering = ["-my_field_name"]    # Métodos    def get_absolute_url(self):         """         Devuelve la url para acceder a una instancia particular de MyModelName.         """         return reverse('model-detail-view', args=[str(self.id)])    def __str__(self):        """        Cadena para representar el objeto MyModelName (en el sitio de Admin, etc.)        """        return self.field_name

En las secciones de abajo exploraremos cada una de las características interiores de un modelo en detalle:

Campos

Un modelo puede tener un número arbitrario de campos, de cualquier tipo. Cada uno representa una columna de datos que queremos guardar en nuestras tablas de la base de datos. Cada registro de la base de datos (fila) consistirá en uno de cada posible valor del campo. Echemos un vistazo al ejemplo visto arriba:

js
my_field_name = models.CharField(  (max_length = 20),  (help_text = "Enter field documentation"),);

Nuestro ejemplo de arriba tiene un único campo llamadomy_field_name, de tipomodels.CharField — lo que significa que este campo contendrá una cadena de caracteres alfanuméricos. Los tipos de campo son asignados usando clases específicas, que determinan el tipo de registro que se usa para guardar el dato en la base, junto con un criterio de evaluación que se usará cuando se reciban los valores de un formulario HTML (es decir, qué constituye un valor válido). Los tipos de campo pueden también tomar argumentos que especifican además cómo se guarda o cómo se puede usar. En este caso le damos a nuestro campo dos argumentos:

  • max_length=20 — Establece que la longitud máxima del valor de este campo es 20 caracteres.
  • help_text="Enter field documentation" — proporciona una etiqueta de texto para mostrar que ayuda a los usuarios a saber qué valor proporcionar cuando un usuario ha de introducirlo via un formulario HTML.

El nombre del campo se usa para referirnos a él en consultas (queries) y plantillas (templates). Los campos también tienen una etiqueta, que puede ser especificada como argumento (verbose_name) o inferida automáticamente, a partir del nombre de variable que identifica al campo, capitalizando la primera letra y reemplazando los guiones bajos por espacios (por ejemplomy_field_name tendría la etiqueta por defecto deMy field name). El orden en que los campos son declarados afectará su orden por defecto si un modelo es renderizado en un formulario (ej. en el sitio de Administración), aunque este comportamiento se puede anular.

Argumentos comunes de los campos

Los siguientes argumentos son comunes a la mayoría de los tipos de campo y pueden usarse al declararlos:

  • help_text: Proporciona una etiqueta de texto para formularios HTML (ej. en el sitio de Administración), tal como se describe arriba.
  • verbose_name: Nombre de fácil lectura que se usa en etiquetas para el campo. Si no se especifica, Django inferirá el valor por defecto del verbose name a partir del nombre del campo.
  • default: Valor por defecto para el campo. Puede ser un valor o uncallable object (objeto que puede ser llamado como una función), en cuyo caso el objeto será llamado cada vez que se cree un nuevo registro.
  • null: Si esTrue, Django guardará valores en blanco o vacíos comoNULL en la base de datos para campos donde sea apropiado (unCharField guardará una cadena vacía en su lugar). Por defecto esFalse.
  • blank: Si esTrue, se permite que el campo quede en blanco en tus formularios. El valor por defecto esFalse, lo que significa que la validación de formularios de Django te forzará a introducir un valor. Con frecuencia se usa connull=True, porque si vas a permitir valores en blanco, también querrás que la base de datos sea capaz de representarlos de forma apropiada.
  • choices: Un grupo de valores de selección para este campo. Si se proporciona, el widget correspondiente por defecto del formulario será una caja de selección con estos valores de selección en vez del campo de texto estándar.
  • primary_key: Si esTrue, establece el campo actual como clave primaria para el modelo (Una clave primaria es una columna especial de la base de datos, diseñada para identificar de forma única todos los diferentes registros de una tabla). Si no se especifica ningún campo como clave primaria, Django añadirá automáticamente un campo para este propósito.

Hay muchas otras opciones — puedes ver lalista completa de opciones aquí.

Tipos comunes de campos

La lista siguiente describe algunos de los tipos de campo más comunmente usados.

  • CharField se usa para definir cadenas de longitud corta a media. Debes especificar lamax_length (longitud máxima) de los datos que se guardarán.
  • TextField se usa para cadenas de longitud grande o arbitraria. Puedes especificar unamax_length para el campo, pero sólo se usa cuando el campo se muestra en formularios (no se fuerza al nivel de la base de datos).
  • IntegerField es un campo para almacenar valores de números enteros y para validar los valores introducidos como enteros en los formularios.
  • DateField yDateTimeField se usan para guardar/representar fechas e información fecha/hora (como en los objetos Pythondatetime.date ydatetime.datetime, respectivamente). Estos campos pueden adicionalmente declarar los parámetros (mutuamente excluyentes)auto_now=True (para establecer el campo a la fecha actual cada vez que se guarda el modelo),auto_now_add (para establecer sólo la fecha cuando se crea el modelo por primera vez), ydefault (para establecer una fecha por defecto que puede ser sobreescrita por el usuario).
  • EmailField se usa para validar direcciones de correo electrónico.
  • FileField eImageField se usan para subir ficheros e imágenes respectivamente (elImageField añade simplemente una validación adicional de que el fichero subido es una imagen). Éstos tienen parámetros para definir cómo y donde se guardan los ficheros subidos.
  • AutoField es un tipo especial deIntegerField que se incrementa automáticamente. Cuando no especificas una clave primaria para tu modelo, se añade -automáticamente- una de éste tipo.
  • ForeignKey se usa para especificar una relación uno a muchos con otro modelo de la base de datos (ej. un coche tiene un fabricante, pero un fabricante puede hacer muchos coches). El lado "uno" de la relación es el modelo que contiene la clave.
  • ManyToManyField se usa para especificar una relación muchos a muchos (ej. un libro puede tener varios géneros, y cada género puede contener varios libros). En nuestra aplicación de la biblioteca usaremos ésta de forma muy similar aForeignKeys, pero pueden usarse de formas más complicadas para describir las relaciones entre grupos. Éstas tienen el parámetroon_delete para definir que ocurre cuando un registro asociado se borra (ej. un valor demodels.SET_NULL establecería simplemente el valor aNULL).

Hay muchos otros tipos de campos, incluyendo campos para diferentes tipos de números (enteros grandes, enteros pequeños, en coma flotante), boleanos, URLs, slugs, identificadores únicos, y otra información relacionada con el tiempo (duración, hora, etc..). Puedes ver lalista completa aquí.

Metadatos

Puedes declarar metadatos a nivel de modelo para tu Modelo declarandoclass Meta, tal como se muestra.

python
class Meta:    ordering = ["-my_field_name"]    ...

Una de las características más útiles de estos metadatos es controlar elorden por defecto de los registros que se devuelven cuando se consulta el tipo de modelo. Se hace especificando el orden de comprobación en una lista de nombres de campo en el atributoordering, como se muestra arriba. La ordenación dependerá del tipo de campo (los campos de caracteres de ordenan alfabéticamente, mientras que los campos de fechas están clasificados por orden cronológico). Como se muestra arriba, se puede invertir el orden de clasificación añadiendo el símbolo (-) como prefijo del nombre del campo.

Así como ejemplo, si elegimos clasificar los libros de esta forma por defecto:

python
ordering = ["title", "-pubdate"]

los libros serán clasificados alfabéticamente por título, de la A al a Z, y luego por fecha de publicación dentro de cada título, desde el más reciente al más antiguo.

Otro atributo común esverbose_name, un nombre descriptivo para la clase en forma singular y plural:

python
verbose_name = "BetterName"

Otros atributos útiles te permiten crear y aplicar nuevos "permisos de acceso" para el modelo (los permisos por defecto se aplican automáticamente), te permiten la ordenación basado en otro campo, o declarar que la clase es "abstracta" (una clase base para la que no vas a crear registros, y que en cambio se derivará para crear otros modelos).

Muchas de las otras opciones de metadatos controlan qué base datos debe usarse para el modelo y cómo se guardan los datos (éstas son realmente útiles si necesitas mapear un modelo a una base datos existente).

La lista completa de opciones de metadatos está disponible aquí:Opciones de metadatos de Modelos (Django docs).

Metodos

Un modelo puede tener también métodos

Minimamente, en cada modelo deberías definir el método estándar de las clases de Python__str__() para devolver una cadena de texto legible por humanos para cada objeto. Esta cadena se usa para representar registros individuales en el sitio de administración (y en cualquier otro lugar donde necesites referirte a una instancia del modelo). Con frecuencia éste devolverá un título o nombre de campo del modelo.

python
def __str__(self):    return self.field_name

Otro método común a incluir en los modelos de Django esget_absolute_url(), que devuelve un URL para presentar registros individuales del modelo en el sitio web (si defines este método, Django añadirá automáticamente un botón "Ver en el sitio" en la ventana de edición del registro del modelo en el sitio de Administración). Un patrón típico paraget_absolute_url() se muestra abajo.

python
def get_absolute_url(self):    """     Devuelve la url para acceder a una instancia particular del modelo.    """    return reverse('model-detail-view', args=[str(self.id)])

Nota:Asumiendo que usarás URLs tipo/myapplication/mymodelname/2 para presentar registros individuales para tu modelo (donde "2" es elid de un registro en particular), necesitarás crear un mapeador URL para pasar la respuesta e id a la "vista detallada del modelo (model detail view)" (que hará el trabajo requerido para presentar el registro). La funciónreverse() de arriba es capaz de "invertir" tu mapeador url (llamado'model-detail-view' en el caso de arriba) para crear una URL del formato correcto.

Por supuesto para hacer este trabajo ¡tienes aún que escribir el mapeo URL, la vista y la plantilla!

Puedes también definir todos los métodos que te apetezca y llamarlos desde tu código o plantillas (siempre y cuando no reciban ningún parámetro).

Gestión de Modelos

Una vez que has definido tus clases de modelos puedes usarlas para crear, actualizar o borrar registros, y ejecutar consultas para obtener todos los registros o subconjuntos particulares de registros. Te mostraremos cómo hacer eso en el tutorial cuando definamos nuestras vistas, pero aquí va un breve resumen.

Creación y modificación de registros

Para crear un registro puedes definir una instancia del modelo y llamar asave().

python
# Creación de un nuevo registro usando el constructor del modelo.a_record = MyModelName(my_field_name="Instancia #1")# Guardar el objeto en la base de datos.a_record.save()

Nota:Si no has declarado ningún campo comoprimary_key, al nuevo registro se le proporcionará una automáticamente, con el nombre de campoid. Puedes consultar este campo después de guardar el registro anterior y debería tener un valor de 1.

Puedes acceder a los campos de este nuevo registro usando la sintaxis de puntos y cambiar los valores. Tienes que llamar asave() para almacenar los valores modificados en la base de datos.

python
# Accesso a los valores de los campos del modelo usando atributos Python.print(a_record.id) # Debería devolver 1 para el primer registro.print(a_record.my_field_name) # Debería imprimir 'Instancia #1'# Cambio de un registro modificando los campos llamando a save() a continuación.a_record.my_field_name="Nuevo Nombre de Instancia"a_record.save()

Búsqueda de registros

Puedes buscar registros que coincidan con un cierto criterio usando el atributoobjects del modelo (proporcionado por la clase base).

Nota:Explicar cómo buscar registros usando un modelo y nombres de campo "abstractos" puede resultar un poco confuso. En la exposición de abajo nos referiremos a un modeloBook con campostitle ygenre, donde genre (género) es también un modelo con un solo camponame.

Podemos obtener todos los registros de un modelo comoQuerySet, usandoobjects.all(). ElQuerySet es un objeto iterable, significando que contiene un número de objetos por los que podemos iterar/hacer bucle.

python
all_books = Book.objects.all()

El método de Djangofilter() nos permite filtrar elQuerySet devuelto para que coincida un campo detexto onumérico con un criterio particular. Por ejemplo, para filtrar libros que contengan la palabra "wild" en el título y luego contarlos, podemos hacer lo siguiente:

python
wild_books = Book.objects.filter(title__contains='wild')number_wild_books = Book.objects.filter(title__contains='wild').count()

Los campos a buscar y el tipo de coincidencia son definidos en el nombre del parámetro de filtro, usando el formato:field_name__match_type (ten en cuenta eldoble guión bajo entretitle ycontains anterior). En el ejemplo anterior estamos filtrandotitle por un valor sensible a mayúsculas y minúsculas. Puedes hacer otros muchos tipos de coincidencias:icontains (no sensible a mayúsculas ni minúsculas),iexact (coincidencia exacta no sensible a mayúsculas ni minúsculas),exact (coincidencia exacta sensible a mayúsculas y minúsculas) ein,gt (mayor que),startswith, etc. Puede ver lalista completa aquí.

En algunos casos, necesitarás filtrar por un campo que define una relación uno-a-muchos con otro modelo (por ejemplo, unaForeignKey). En estos casos puedes "referenciar" a campos dentro del modelo relacionado con un doble guión bajo adicional. Así, por ejemplo, para filtrar los libros de un género específico tienes que referenciar elname a través del campogenre como se muestra más abajo:

python
books_containing_genre = Book.objects.filter(genre__name__icontains='fiction')  # Will match on: Fiction, Science fiction, non-fiction etc.

Nota:Puedes usar guiones bajos (__) para navegar por tantos niveles de relaciones (ForeignKey/ManyToManyField) como quieras. Por ejemplo, un Book que tuviera diferentes "types", definidos usando una relación adicional "cover", podría tener un nombre de parámetro:type__cover__name__exact='hard'.

Puedes hacer muchas más cosas con las consultas, incluyendo búsquedas hacia atrás de modelos relacionados, filtros encadenados, devolver un conjunto de valores más pequeño, etc. Para más información, puedes consultarElaborar consultas (Django Docs).

Definiendo los Modelos de LocalLybrary

En esta sección comenzaremos a definir los modelos para nuestra biblioteca. Abremodels.py (en /locallibrary/catalog/). El código de más arriba importa el módulomodels que contiene la clasemodels.Model, que servirá de base para nuestros modelos:

python
from django.db import models# Create your models here.

Modelo 'Genre'

Copia el código del modeloGenre que se muestra abajo y pégalo al final de tu archivomodels.py. Este modelo nos servirá para almacenar información relativa a la categoría del libro (por ejemplo, si es ficción o no, si es un romancero o es un libro de historia, etc.) Como se dijo más arriba, preferimos modelar el género (Genre) como una entidad, en vez de utilizar un campo de texto o una lista de opciones, porque de esta manera es posible manejar los valores a través de nuestra base de datos, en vez de fijarlo en el código (hard-coding)

python
class Genre(models.Model):    """    Modelo que representa un género literario (p. ej. ciencia ficción, poesía, etc.).    """    name = models.CharField(max_length=200, help_text="Ingrese el nombre del género (p. ej. Ciencia Ficción, Poesía Francesa etc.)")    def __str__(self):        """        Cadena que representa a la instancia particular del modelo (p. ej. en el sitio de Administración)        """        return self.name

El modelo tiene un único campo (name), de tipoCharField, que usaremos para describir el género literario. Este campo tiene un tamaño máximo (max_length) de 200 caracteres y, además, posee unhelp_text. Al final de la clase, hemos declarado el método__str__(), que simplemente devuelve el nombre de un género definido por un registro en particular. Como no hemos definido un nombre explicativo (verbose_name) para nuestro campo, éste se establecerá enName y se mostrará de esa manera en los formularios.

Modelo 'Book'

Copia el código del modeloBook que aparece más abajo y pégalo al final de tu archivo. El modelo Libro representa la información que se tiene sobre un libro, en sentido general, pero no sobre un libro particular que se encuentre disponible en la biblioteca. Este modelo utiliza campos de tipoCharField para representar el título (title) y elisbn del libro (nota que el campoisbn especifica su etiqueta como "ISBN" utilizando el primer parámetro posicional, ya que la etiqueta por defecto hubiera sido "Isbn"). Además tenemos un campo para la sinopsis (summary), de tipoTextField, ya que este texto podría ser bastante largo.

python
from django.urls import reverse #Used to generate URLs by reversing the URL patternsclass Book(models.Model):    """    Modelo que representa un libro (pero no un Ejemplar específico).    """    title = models.CharField(max_length=200)    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)    # ForeignKey, ya que un libro tiene un solo autor, pero el mismo autor puede haber escrito muchos libros.    # 'Author' es un string, en vez de un objeto, porque la clase Author aún no ha sido declarada.    summary = models.TextField(max_length=1000, help_text="Ingrese una breve descripción del libro")    isbn = models.CharField('ISBN',max_length=13, help_text='13 Caracteres <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>')    genre = models.ManyToManyField(Genre, help_text="Seleccione un genero para este libro")    # ManyToManyField, porque un género puede contener muchos libros y un libro puede cubrir varios géneros.    # La clase Genre ya ha sido definida, entonces podemos especificar el objeto arriba.    def __str__(self):        """        String que representa al objeto Book        """        return self.title    def get_absolute_url(self):        """        Devuelve el URL a una instancia particular de Book        """        return reverse('book-detail', args=[str(self.id)])

El género es un campo de tipoManyToManyField, de manera tal que un mismo libro podrá abarcar varios géneros y un mismo género podrá abarcar muchos libros. El autor es declarado comoForeignKey, de modo que cada libro podrá tener un sólo autor, pero un autor podrá tener muchos libros (en la vida real, un mismo libro puede tener varios autores, pero en nuestra implementación no).

En la declaración de ambos campos, el modelo relacionado se ingresa como primer parámetro posicional, usando el nombre la clase que lo implementa o, bien, el nombre del modelo como string, si éste no ha sido implementado en el archivo, antes de la declaración del campo. Otros parámetros interesantes que podemos observar, en el campoauthor, sonnull=True, que permite a la base de datos almacenarnull si el autor no ha sido seleccionado, yon_delete=models.SET_NULL, que pondrá ennull el campo si el registro del autor relacionado es eliminado de la base de datos.

El modelo también define__str__(), usando el campotitle para representar un registro de la claseBook. El último método,get_absoulte_url() devuelve un URL que puede ser usado para acceder al detalle de un registro particular (para que esto funcione, debemos definir un mapeo de URL que tenga el nombrebook-detail y una vista y una plantilla asociadas a él)

Modelo 'BookInstance'

A continuación, copie el modelBookInstance (mostrado a continuación) debajo de los otros modelos.BookInstance representa una copia específica de un libro que alguien pueda pedir prestado, en incluye información sobre si la copia esta disponible o sobre cual es la fecha que se espera sea devuelto, "imprenta" o detalles de versión, y un id único para el libro en la biblioteca.

Algunos de los campos y métodos ahora serán familiares. El modelo usa

  • ForeignKey para identificar el Libro asociado (cada libro puede tener muchas copias, pero una copia solo puede tener unBook).
  • CharField para representar la imprenta (publicación específica) del libro.
python
import uuid # Requerida para las instancias de libros únicosclass BookInstance(models.Model):    """    Modelo que representa una copia específica de un libro (i.e. que puede ser prestado por la biblioteca).    """    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text="ID único para este libro particular en toda la biblioteca")    book = models.ForeignKey('Book', on_delete=models.SET_NULL, null=True)    imprint = models.CharField(max_length=200)    due_back = models.DateField(null=True, blank=True)    LOAN_STATUS = (        ('m', 'Maintenance'),        ('o', 'On loan'),        ('a', 'Available'),        ('r', 'Reserved'),    )    status = models.CharField(max_length=1, choices=LOAN_STATUS, blank=True, default='m', help_text='Disponibilidad del libro')    class Meta:        ordering = ["due_back"]    def __str__(self):        """        String para representar el Objeto del Modelo        """        return '%s (%s)' % (self.id,self.book.title)

Adicionalmente hemos declarado algunos tipos nuevos de campos:

  • UUIDField es usado para establecer el campoid como unaprimary_key para este modelo. Este tipo de campo asigna un único valor global para cada instancia ( uno para cada libro que puedes encontrar en la biblioteca).
  • DateField es usado para la fechadue_back (en la que se espera que el libro este diponible despues de ser prestado o estar en mantenimiento). Este valor puede serblank onull (necesario cuando el libro esta disponible). El patrón metadata (Class Meta) usa este campo para ordenar registros cuando se retornan en una consulta.
  • status es unCharField que define una lista de elección/selección. Como puedes ver, hemos definido una tupla que contiene tuplas de pares clave-valor y los pasamos a los argumentos de choice. El valor en un par clave/valor es un valor desplegable que el usuario puede seleccionar, mientras las claves son valores que en realidad son guardados en la opción seleccionada. Tambien establecemos un valor por defecto de 'm' (maintenance) ya que los libros inicialmente se crearán como no disponibles antes de que esten almacenados en los estantes.

El patrón__str__() representa el objetoBookInstance usando una combinación de su id único y el título delBook asociado.

Nota:Un poco de Python:

El valor retornado por__str__() es unacadena formateada. Dentro de la cadena usamos%s para declarar "marcadores de posición". Después de la cadena ponemos% y después una tupla que contiene los valores que serán puestos en los marcadores de posición. Si solo tienes un marcador de posición entonces puedes omitir la tupla — e.j.'Mi valor: %s' % variable.

Note que aunque este enfoque es perfectamente válido, sea conciente que ya no es preferido. Desde Python 3 debes usar en su lugar el métodoformat, ej.'{0} ({1})'.format(self.id,self.book.title). Puedes leer más sobre estoaquí. A partir de Python 3.6 también puedes usar la sintaxis de interpolación de cadena, e.j.f'{self.id} ({self.book.title})'.

Modelo 'Author'

Copia el modeloAuthor (mostrado abajo) bajo el código existente enmodels.py.

Todos los campos/métodos ahora deben ser familiares. El modelo define a un autor que tiene un primer nombre, apellido, fecha de nacimiento, y (opcional) fecha de fallecimiento. Especifica que de forma predeterminada el__str__() retorna el nombre en elorden apellido,primer nombre. El métodoget_absolute_url() invierte el mapeo URLauthor-detail para obtener el URL para mostrar un autor individual.

python
class Author(models.Model):    """    Modelo que representa un autor    """    first_name = models.CharField(max_length=100)    last_name = models.CharField(max_length=100)    date_of_birth = models.DateField(null=True, blank=True)    date_of_death = models.DateField('Died', null=True, blank=True)    def get_absolute_url(self):        """        Retorna la url para acceder a una instancia particular de un autor.        """        return reverse('author-detail', args=[str(self.id)])    def __str__(self):        """        String para representar el Objeto Modelo        """        return '%s, %s' % (self.last_name, self.first_name)

Reiniciar las migraciones a la base de datos

Todos tus modelos han sido creados. Para añadirlos a tu base de datos, vuelve a ejecutar las migraciones de tu base de datos.

bash
python3 manage.py makemigrationspython3 manage.py migrate

Modelo 'Language' - desafío

Imagina que un benefactor local dona un número de libros nuevos escritos en otro lenguaje (digamos, Farsi). El desafío es averiguar como estos pueden ser bien representados en tu sitio Web, y luego agregarlos a los modelos.

Algunas cosas a considerar:

  • ¿Debe asociarse un "lenguaje" a unBook,BookInstance, o algún otro objeto?
  • ¿Deberian representarse los diferentes idiomas usando un modelo, un campo de texto libre o una lista de seleccion codificada?

Después que hayas decidido, agrega el campo. Puedes ver que decidimos nostros en Githubaquí.

No olvides que después de un cambio en tu modelo, debes volver a hacer las migraciones para que se apliquen los cambios en tu base de datos.

bash
python3 manage.py makemigrationspython3 manage.py migrate

Resumen

En este artículo hemos aprendido como son definidos los modelos, y luego usar esta información para diseñar e implementar modelos apropiados para el sitio WebLocalLibrary.

En este punto nos desviaremos brevemente de la creación del sitio, y miraremos elsitio de Administración deDjango. Este sitio nos permitirá añadir algunos datos a la biblioteca, los cuales podemos mostrar usando nuestras (aún por crear) vistas y plantillas.

Vea también

Help improve MDN

Learn how to contribute

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2026 Movatter.jp