Esta traducción está incompleta. Por favor, ayuda a traducir este artículo del inglés.

Este artículo muestra cómo definir modelos para el sitio web de la BibliotecaLocal. Explica lo que es un modelo, cómo se declara, y algunos de los principales tipos de campos. Muestra también brevemente unas pocas de las maneras principales en que puedes acceder 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 la estructura de los datos almacenados, incluidos los tipos de campo y posiblemente también 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 otro código, y Django se encarga de todo el trabajo sucio de comunicarse con la base de datos por usted.

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

Diseñando los modelos de LocalLibrary

Antes de saltar y comenzar a codificar los modelos, vale la pena tomarse unos minutos para pensar qué datos necesitamos almacenar y 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 todas las opciones o cambio. 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 nuestros modelos y nuestro campo, debemos pensar en las relaciones. Django le permite definir relaciones que son 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 el BookInstance:status — hemos codificado 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, incluidas sus multiplicidades. Las multiplicidades son los números en el diagrama que muestran los números (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 que BookGenre están relacionados. Los números cercanos al modeloBook muestran que un libro debe tener uno o más Genres (tantos como desee), mientras que los números al otro lado de la línea al lado de Genre 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 algún archivo models.py de la aplicación. Son implementados como subclases de django.db.models.Model, y pueden incluir campos, métodos y metadata. El fragmento de código más abajo muestra un modelo "típico", llamado MyModelName:

from django.db import models

class 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:

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

Nuestro ejemplo de arriba tiene un único campo llamado my_field_name, de tipo models.CharField — lo que significa que este campo contendrá cadenas 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 queries y plantillas. Los campos también tienen una etiqueta, que o es especificada como argumento (verbose_name) o inferida mediante capitalización de la primera letra del nombre de la variable del campo y reemplazando cualquier guión bajo por un espacio (por ejemplo my_field_name tendría la etiqueta por defecto de My 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 Adminsitración), aunque este comportamiento se puede anular.

Argumentos comunes de los campos

Los siguientes argumentos comunes pueden usarse cuando se declaran muchos/la mayoría de los diferentes tipos de campos:

  • help_text: Proporciona una etiqueta de texto para formularios HTML (ej. en el sitio de Administración), tal como se describe arriba.
  • verbose_name: A nombre de fácil lectura para el campo que se usa en etiquetas del 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 un callable 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 True, Django guardará valores en blanco o vacíos como NULL en la base de datos para campos donde sea apropiado (un CharField guardará una cadena vacía en su lugar). Por defecto es False.
  • blank: Si True, se permite que el campo quede en blanco en tus formularios. El valor por defecto es False, que significa que la validación de formularios de Django te forzará a introducir un valor. Con frecuencia se usa con null=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ándard.
  • primary_key: Si True, 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 la base de datos). Si no se especifica ningún campo como clave primaria Django añadirá automáticamente uno campo para este propósito.

Hay muchas otras opciones — puedes ver la lista 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 la max_length (longitud máxima) de los datos que se guardarán.
  • TextField se usa para cadenas de longitud grande o arbitraria. Puedes especificar una max_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 (número completo) y para validar los valores introducidos como enteros en los formularios.
  • DateField y DateTimeField se usan para guardar/representar fechas e información fecha/hora (como en los objetos Python datetime.date  y datetime.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), y default (para establecer una fecha por defecto que puede ser sobreescrita por el usuario).
  • EmailField se usa para validar direcciones de correo electrónico.
  • FileField e ImageField se usan para subir ficheros e imágenes respectivamente (el ImageField 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 de IntegerField que se incrementa automáticamente. Se añade automáticamente una clave primaria a tu modelo si no especificas explícitamente una.
  • 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 a ForeignKeys, pero pueden usarse de formas más complicadas para describir las relaciones entre grupos. Éstas tienen el parámetro on_delete para definir que ocurre cuando un registro asociado se borra (ej. un valor de models.SET_NULL establecería simplemente el valor a NULL).

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 la lista completa aquí.

Metadatos

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

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

Una de las características más útiles de estos metadatos es controlar el orden 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 atributo ordering, 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:

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 es verbose_name, un nombre descriptivo para la clase en forma singular y plural:

verbose_name = "BetterName"

Otros atributos útiles te permiten crear y aplicar nuevos "permisos de accesos" 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 que 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 humanamente-legible 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.

def __str__(self):
    return self.field_name

Otro método común a incluir en los modelos de Django es get_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 para get_absolute_url() se muestra abajo.

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 el id 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ón reverse() 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 cuantos otros métodos que te apetezcan y llamarlos desde tu código o plantillas (teniendo en cuenta que no pueden utilizar 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 a save().

# 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 como primary_key, al nuevo registro se le proporcionará una automáticamente, con el nombre de campo id. 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 a save() para almacenar los valores modificados en la base de datos.

# 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 atributo objects del modelo (proporcionado por la clase base).

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

Podemos obtener todos los regsitros de un modelo como QuerySet, usando objects.all(). El QuerySet es un objeto iterable, significando que contiene un número de objetos por los que podemos iterar/hacer bucle.

all_books = Book.objects.all()

El método de Django filter() nos permite filtrar el QuerySet devuelto para que coincida un campo de texto o numé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:

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 el doble guión bajo entre titlecontains anterior). En el ejemplo anterior estamos filtrando title 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) e in, gt (mayor que), startswith, etc. Puede ver la lista completa aquí.

En algunos casos, necesitarás filtrar por un campo que define una relación uno-a-muchos con otro modelo (por ejemplo, una ForeignKey). 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 el name a través del campo genre como se muestra más abajo:

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 consultar Elaborar consultas (Django Docs).

Defining the LocalLibrary Models

In this section we will start defining the models for the library. Open models.py (in /locallibrary/catalog/). The boilerplate at the top of the page imports the models module, which contains the model base class models.Model that our models will inherit from.

from django.db import models

# Create your models here.

Genre model

Copy the Genre model code shown below and paste it into the bottom of your models.py file. This model is used to store information about the book category — for example whether it is fiction or non-fiction, romance or military history, etc. As mentioned above, we've created the Genre as a model rather than as free text or a selection list so that the possible values can be managed through the database rather than being hard coded.

class Genre(models.Model):
    """
    Model representing a book genre (e.g. Science Fiction, Non Fiction).
    """
    name = models.CharField(max_length=200, help_text="Enter a book genre (e.g. Science Fiction, French Poetry etc.)")
    
    def __str__(self):
        """
        String for representing the Model object (in Admin site etc.)
        """
        return self.name

The model has a single CharField field (name), which is used to describe the genre (this is limited to 200 characters and has some help_text. At the end of the model we declare a __str__() method, which simply returns the name of the genre defined by a particular record. No verbose name has been defined, so the field will be called Name in forms.

Book model

Copy the Book model below and again paste it into the bottom of your file. The book model represents all information about an available book in a general sense, but not a particular physical "instance" or "copy" available for loan. The model uses a CharField to represent the book's title and isbn (note how the isbn specifies its label as "ISBN" using the first unnamed parameter because the default label would otherwise be "Isbn"). The model uses TextField for the summary, because this text may need to be quite long.

from django.urls import reverse #Used to generate URLs by reversing the URL patterns

class Book(models.Model):
    """
    Model representing a book (but not a specific copy of a book).
    """
    title = models.CharField(max_length=200)
    author = models.ForeignKey('Author', on_delete=models.SET_NULL, null=True)
    # Foreign Key used because book can only have one author, but authors can have multiple books
    # Author as a string rather than object because it hasn't been declared yet in the file.
    summary = models.TextField(max_length=1000, help_text="Enter a brief description of the book")
    isbn = models.CharField('ISBN',max_length=13, help_text='13 Character <a href="https://www.isbn-international.org/content/what-isbn">ISBN number</a>')
    genre = models.ManyToManyField(Genre, help_text="Select a genre for this book")
    # ManyToManyField used because genre can contain many books. Books can cover many genres.
    # Genre class has already been defined so we can specify the object above.
    
    def __str__(self):
        """
        String for representing the Model object.
        """
        return self.title
    
    
    def get_absolute_url(self):
        """
        Returns the url to access a particular book instance.
        """
        return reverse('book-detail', args=[str(self.id)])

The genre is a ManyToManyField, so that a book can have multiple genres and a genre can have many books. The author is declared as ForeignKey, so each book will only have one author, but an author may have many books (in practice a book might have multiple authors, but not in this implementation!)

In both field types the related model class is declared as the first unnamed parameter using either the model class or a string containing the name of the related model. You must use the name of the model as a string if the associated class has not yet been defined in this file before it is referenced! The other parameters of interest in the author field are null=True, which allows the database to store a Null value if no author is selected, and on_delete=models.SET_NULL, which will set the value of the author to Null if the associated author record is deleted.

The model also defines __str__() , using the book's title field to represent a Book record. The final method, get_absolute_url() returns a URL that can be used to access a detail record for this model (for this to work we will have to define a URL mapping that has the name book-detail, and define an associated view and template).

BookInstance model

Next, copy the BookInstance model (shown below) under the other models. The BookInstance represents a specific copy of a book that someone might borrow, and includes information about whether the copy is available or on what date it is expected back, "imprint" or version details, and a unique id for the book in the library.

Some of the fields and methods will now be familiar. The model uses

  • ForeignKey to identify the associated Book (each book can have many copies, but a copy can only have one Book).
  • CharField to represent the imprint (specific release) of the book.
import uuid # Required for unique book instances

class BookInstance(models.Model):
    """
    Model representing a specific copy of a book (i.e. that can be borrowed from the library).
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, help_text="Unique ID for this particular book across whole library")
    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='Book availability')

    class Meta:
        ordering = ["due_back"]
        

    def __str__(self):
        """
        String for representing the Model object
        """
        return '%s (%s)' % (self.id,self.book.title)

We additionally declare a few new types of field:

  • UUIDField is used for the id field to set it as the primary_key for this model. This type of field allocates a globally unique value for each instance (one for every book you can find in the library).
  • DateField is used for the due_back date (at which the book is expected to come available after being borrowed or in maintenance). This value can be blank or null (needed for when the book is available). The model metadata (Class Meta) uses this field to order records when they are returned in a query.
  • status is a CharField that defines a choice/selection list. As you can see, we define a tuple containing tuples of key-value pairs and pass it to the choices argument. The value in a key/value pair is a display value that a user can select, while the keys are the values that are actually saved if the option is selected. We've also set a default value of 'm' (maintenance) as books will initially be created unavailable before they are stocked on the shelves.

The model __str__() represents the BookInstance object using a combination of its unique id and the associated Book's title.

Note: A little Python:

  • The value returned by __str__() is a formatted string. Within the string we use %s to declare "placeholders'. After the string we specify % and then a tuple containing the values to be inserted in the placeholders. If you just have one placeholder then you can omit the tuple — e.g. 'My value: %s' % variable.

    Note also that although this approach is perfectly valid, please be aware that it is no longer prefered. Since Python 3 you should instead use the format method, eg. '{0} ({1})'.format(self.id,self.book.title). You can read more about it here. Starting with Python 3.6 you can also use the string interpolation syntax, e.g. f'{self.id} ({self.book.title})'.

Author model

Copy the Author model (shown below) underneath the existing code in models.py.

All of the fields/methods should now be familiar. The model defines an author as having a first name, last name, date of birth, and (optional) date of death. It specifies that by default the __str__() returns the name in last name, firstname order. The get_absolute_url() method reverses the author-detail URL mapping to get the URL for displaying an individual author.

class Author(models.Model):
    """
    Model representing an author.
    """
    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):
        """
        Returns the url to access a particular author instance.
        """
        return reverse('author-detail', args=[str(self.id)])
    

    def __str__(self):
        """
        String for representing the Model object.
        """
        return '%s, %s' % (self.last_name, self.first_name)

Re-run the database migrations

All your models have now been created. Now re-run your database migrations to add them to your database.

python3 manage.py makemigrations
python3 manage.py migrate

Language model — challenge

Imagine a local benefactor donates a number of new books written in another language (say, Farsi). The challenge is to work out how these would be best represented in our library website, and then to add them to the models.

Some things to consider:

  • Should "language" be associated with a Book, BookInstance, or some other object?
  • Should the different languages be represented using model, a free text field, or a hard-coded selection list?

After you've decided, add the field. You can see what we decided on Github here.

Summary

In this article we've learned how models are defined, and then used this information to design and implement appropriate models for the LocalLibrary website.

At this point we'll divert briefly from creating the site, and check out the Django Administration site. This site will allow us to add some data to the library, which we can then display using our (yet to be created) views and templates.

See also

 

In this module

 

Etiquetas y colaboradores del documento

 Colaboradores en esta página: SgtSteiner, javierdelpino, Panchosama, MatiMateo
 Última actualización por: SgtSteiner,