Escribiendo su primera aplicación en Django, parte 2¶
Este tutorial comienza donde quedó el Tutorial 1. Vamos a configurar la base de datos, crear su primer modelo y recibir una introducción rápida al sitio administrativo generado automáticamente de Django.
Configuración de la base de datos¶
Ahora, abra el archivo mysite/settings.py
. Es un módulo normal de Python con variables de nivel de módulo que representan la configuración de Django.
By default, the configuration uses SQLite. If you’re new to databases, or you’re just interested in trying Django, this is the easiest choice. SQLite is included in Python, so you won’t need to install anything else to support your database. When starting your first real project, however, you may want to use a more scalable database like PostgreSQL, to avoid database-switching headaches down the road.
Si desea utilizar otra base de datos, instale los enlaces de base de datos apropiados <database-installation>`, y cambie las siguientes claves en el ítem DATABASES
'default'
para que se ajusten a la configuración de conexión de la base de datos:
ENGINE
– bien sea'django.db.backends.sqlite3'
,'django.db.backends.postgresql_psycopg2'
,'django.db.backends.mysql'
, o'django.db.backends.oracle'
. Otros backends :ref: también están disponibles <third-party-notes>.NAME
–el nombre de su base de datos. Si está utilizando SQLite, la base de datos será un archivo en su computadora; en ese casoNAME
debe ser la ruta absoluta completa, incluyendo el respectivo nombre del archivo. El valor predeterminado,os.path.join(BASE_DIR, 'db.sqlite3')
, guardará el archivo en el directorio de su proyecto.
Si no está utilizando SQLite como su base de datos, se deben añadir ajustes adicionales tales como USER
, PASSWORD
, y HOST
se deben añadir. Para más información, vea la documentación de referencia para DATABASES
.
Para bases de datos distintas a SQLite
Si está utilizando una base de datos SQLite, asegúrese de que ha creado ya la base de datos en este punto. Hágalo con el comando «CREATE DATABASE database_name;
» en la consola interactiva de la base de datos.
Del mismo modo asegúrese de que la base de datos proporcionada en el archivo mysite/settings.py
tiene permisos de tipo «create database». Esto permitirá la creación automática de test database que será necesaria en un tutorial posterior.
Si estás usando SQLite, no es necesario crear nada de antemano - el archivo de base de datos se creará automáticamente cuando sea necesario.
Mientras que usted está editando el archivo mysite/settings.py
, configure TIME_ZONE
a su zona horaria.
Además, observe que la configuración de INSTALLED_APPS
se encuentra en la parte superior del archivo. Esta contiene los nombres de todas las aplicaciones Django que están activadas en esta instancia de Django. Las aplicaciones se pueden usar en diversos proyectos y usted puede empaquetar y distribuirlas para que otras personas las puedan utilizar en sus proyectos.
Por defecto, INSTALLED_APPS
contiene las siguientes aplicaciones y Django viene equipado con todas ellas:
django.contrib.admin
- El sitio administrativo. Usted lo utilizará dentro de poco.django.contrib.auth
– Un sistema de autenticación.django.contrib.contenttypes
– Un framework para los tipos de contenido.django.contrib.sessions
– Un framework de sesión.django.contrib.messages
– Un framework de mensajería.django.contrib.staticfiles
– Un framework para la gestión de archivos estáticos.
Estas aplicaciones se incluyen de forma predeterminada como una conveniencia para el caso común.
Algunas de estas aplicaciones utilizan al menos una tabla de base de datos, por lo que necesitamos crear las tablas en la base de datos antes de poder utilizarlas. Para ello, ejecute el siguiente comando:
$ python manage.py migrate
El comando migrate
analiza la configuración INSTALLED_APPS
y crea las tablas de base de datos necesarias según la configuración de base de datos en su archivo mysite/settings.py
y las migraciones de base de datos distribuidas con la aplicación (trataremos este tema más tarde). Verá un mensaje para cada migración que aplique. Si está interesado, ejecute el cliente de línea de comandos para su base de datos y teclee \dt
(PostgreSQL), SHOW TABLES;
(MySQL), .schema
(SQLite), o SELECT TABLE_NAME FROM USER_TABLES;
(Oracle) para desplegar las tablas que creó Django.
Para los minimalistas
Como dijimos anteriormente, las aplicaciones predeterminadas se incluyen para el caso común, pero no todos las necesitan. Si usted no necesita alguna o ninguna de ellas, no dude en dejar fuera o borrar las línea(s) correspondientes desde INSTALLED_APPS
antes de ejecutar el comando migrate
. El comando migrate
solo ejecutará migraciones para aplicaciones en INSTALLED_APPS
.
Creando modelos¶
A continuación definiremos sus modelos, sobre todo su estructura de base de datos, con metadatos adicionales.
Filosofía
Un modelo es la fuente única y definitiva de información sobre sus datos. Contiene los campos esenciales y los comportamientos de los datos que usted guarda. Django sigue el Principio DRY. El objetivo es definir el modelo de datos en un solo lugar y derivar cosas de este automáticamente.
Este incluye las migraciones, a diferencia de Ruby On Rails, por ejemplo, las migraciones se derivan totalmente de su archivo de modelos y son esencialmente sólo un historial a través del cual Django puede pasar para actualizar su esquema de base de datos para que coincida con sus modelos actuales.
En nuestra sencilla aplicación encuesta, vamos a crear dos modelos:Question
y Choice
. Una Question
tiene una pregunta y una fecha de publicación. Una Choice
tiene dos campos: el texto de la elección y un conteo de votos. Cada Choice
se asocia a una Question
.
Estos conceptos se representan mediante clases sencillas de Python. Edite el archivo polls/models.py
de modo que se vea de la siguiente manera:
from django.db import models
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
El código es sencillo. Cada modelo está representado por una clase que subclasifica django.db.models.Model
. Cada modelo tiene una serie de variables de clase, cada uno de los cuales representa un campo de la base de datos en el modelo.
Cada campo está representado por una instancia de una clase Field
, por ejemplo, CharField
para campos de caracteres y DateTimeField
para variables de tiempo y fecha. Esto le dice a Django qué tipo de datos cada campo contiene.
El nombre de cada instancia Field
(por ejemplo, question_text
o pub_date
)` es el nombre del campo, en formato adaptado al lenguaje de la máquina. Va a usar este valor en el código Python y su base de datos va a usarlo como el nombre de la columna.
Puede emplear un primer argumento posicional opcional a una Field
para designar un nombre legible por humanos. Ese se utiliza en varias partes introspectivas de Django y sirve al mismo tiempo como documentación. Si no se proporciona este campo, Django usará el nombre legible por la máquina. En este ejemplo, sólo hemos definido un nombre legible para Question.pub_date
. Para el resto de los campos en este modelo, el nombre del campo legible por la máquina servirá como el nombre legible por humanos.
Algunas clases Field
precisan argumentos. La clase CharField
, por ejemplo, requiere que usted le asigne un max_length
. Esta se utiliza no sólo en el esquema de la base de datos, sino también en la validación como veremos dentro de poco.
Una clase Field
también puede tener varios argumentos opcionales; en este caso, le hemos fijado al default
el valor de votos
en 0.
Por último, tenga en cuenta que una relación se define usando ForeignKey
. Eso le indica a Django que cada Choice
se relaciona con un sola Question
. Django es compatible con todas las relaciones de bases de datos comunes: varias a una, varias a varias y una a una.
Activando los modelos¶
Ese pequeño fragmento de código de modelo le proporciona a Django mucha información. Con él Django es capaz de:
- Crear un esquema de base de datos para esta aplicación (oraciones
CREATE TABLE
). - Crear una API de acceso a la base datos Python para acceder a los objetos
Question
yChoice
.
Pero primero tenemos que indicarle a nuestro proyecto que la aplicación encuestas
está instalada.
Filosofía
Las aplicaciones Django son «conectables»: Usted puede utilizar una aplicación en diversos proyectos y puede distribuir aplicaciones porque ellas no necesitan estar atadas a una determinada instalación de Django.
To include the app in our project, we need to add a reference to its
configuration class in the INSTALLED_APPS
setting. The
PollsConfig
class is in the polls/apps.py
file, so its dotted path
is 'polls.apps.PollsConfig'
. Edit the mysite/settings.py
file and
add that dotted path to the INSTALLED_APPS
setting. It’ll look like
this:
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
Ahora Django sabe incluir la aplicación polls
. Vamos a ejecutar otro comando:
$ python manage.py makemigrations polls
Usted debe ver algo similar a lo siguiente:
Migrations for 'polls':
polls/migrations/0001_initial.py:
- Create model Choice
- Create model Question
- Add field question to choice
Al ejecutar makemigrations
, usted le indica a Django que ha realizado algunos cambios a sus modelos (en este caso, ha realizado cambios nuevos) y que le gustaría que los guarde como una migración.
Django guarda los cambios en sus modelos como migraciones (y por lo tanto en su esquema de base de datos); son solo archivos en el disco. Usted puede leer la migración para su nuevo modelo si lo desea, es el archivo polls/migrations/0001_initial.py
. No se preocupe, no se espera que usted las lea cada vez que Django hace una, sino que están diseñadas para que sean editables en caso de que usted desee modificar manualmente como Django cambia las cosas.
Hay un comando que ejecutará las migraciones para usted y gestionará el esquema de base de datos automáticamente; este se denomina migrate
, y hablaremos de ello en un momento, pero primero, vamos a ver cuál SQL esa migración ejecutaría . El comando sqlmigrate
recibe nombres de migración y devuelve su SQL:
$ python manage.py sqlmigrate polls 0001
Debería ver algo similar a lo siguiente (lo hemos reformateado para facilitar la lectura):
BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
--
-- Create model Question
--
CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
--
-- Add field question to choice
--
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
COMMIT;
Tenga en cuenta lo siguiente:
- La salida exacta variará dependiendo de la base de datos que esté utilizando. El ejemplo anterior se genera para PostgreSQL.
- Los nombres de las tablas se generan automáticamente combinando el nombre de la aplicación (
polls
) y el nombre del modelo en minúscula;question
ychoice
. (Usted puede anular este comportamiento) - Las claves primarias (IDs) se agregan automáticamente. (Usted también puede anular esto)
- Convencionalmente, Django añade
"_id"
al nombre del campo de la clave externa ( sí, usted también puede anular esto) - La relación de la clave externa se hace explícita por una restricción``FOREIGN KEY``. No se preocupe por las partes
DEFERRABLE
; eso solo le indica a PostgreSQL que no aplique la clave externa hasta el final de la transacción. - Se adapta a la base de datos que está utilizando, así que los tipos de campos específicos de la bases de datos como
auto_increment
(MySQL),serial
(PostgreSQL) ointeger primary key autoincrement
(SQLite) se gestionan de forma automática. Lo mismo se aplica para la cita de nombres de campos, por ejemplo, el uso de comillas dobles o comillas simples. - El comando
sqlmigrate
en realidad no ejecuta la migración en su base de datos, sólo la imprime en la pantalla para que pueda ver lo que SQL Django piensa que se requiere. Es útil para comprobar lo que Django va a hacer o si usted tiene administradores de bases de datos que requieran scripts SQL para introducir cambios.
Si le interesa, usted también puede ejecutar el comando python manage.py check
; este revisa cualquier problema en su proyecto sin hacer migraciones o modificar la base de datos.
A continuación, ejecute de nuevo el comando migrate
para crear esas tablas modelos en su base de datos:
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Rendering model states... DONE
Applying polls.0001_initial... OK
El comando migrate
toma todas las migraciones que no han sido aplicadas (Django rastrea cuales se aplican utilizando una tabla especial en su base de datos llamada django_migrations
) y las ejecuta contra su base de datos; básicamente, sincronizando los cambios que usted ha realizado a sus modelos con el esquema en la base de datos.
Las migraciones son muy potentes y le permiten modificar sus modelos con el tiempo, a medida que desarrolla su proyecto, sin necesidad de eliminar su base de datos o las tablas y hacer otras nuevas. Este se especializa en la actualización de su base de datos en vivo, sin perder datos. Vamos a hablar de ellas en mayor profundidad más tarde en el tutorial, pero por ahora, recuerde la guía de tres pasos para hacer cambios de modelo:
- Cambie sus modelos (en
models.py
). - Ejecute el comando
python manage.py makemigrations
para crear migraciones para esos cambios - Ejecute el comando
python manage.py migrate
para aplicar esos cambios a la base de datos.
La razón por la que hay comandos separados para hacer y aplicar las migraciones es porque usted hará commit de migraciones al sistema de control de versiones y las enviará con su aplicación; ellas no sólo hacen que su desarrollo sea más fácil, también son utilizables por otros desarrolladores y en ambiente de producción.
Lea la documentación del django-admin para obtener información detallada sobre lo que puede hacer la utilidad manage.py
.
Jugando con la API¶
Ahora vayamos al shell interactivo de Python y juguemos con la API gratuita que Django le proporciona. Para llamar el shell de Python, utilice este comando:
$ python manage.py shell
Estamos usando esto en vez de simplemente escribir «python», porque el archivo manage.py
establece la variable de entorno DJANGO_SETTINGS_MODULE
, que le suministra a Django la ruta de importación de Python para su archivo mysite/settings.py
.
Omitiendo manage.py
Si prefiere no utilizar el archivo manage.py
, no hay problema. Sólo tiene que configurar la variable de entorno DJANGO_SETTINGS_MODULE
para mysite.settings
, inicie un shell de Python plano y configure Django:
>>> import django
>>> django.setup()
Si esto produce una AttributeError
, probablemente esté usando una versión de Django que no coincide con la versión del tutorial. Usted querrá ya sea cambiar al tutorial anterior o a la versión más reciente de Django.
Usted debe ejecutar python
desde el mismo directorio en el que está el archivo manage.py
o asegúrese de que el directorio esté en la ruta Python para que import mysite
funcione.
Para obtener más información acerca de todo esto, consulte la documentación del django-admin.
Una vez que esté en el shell, explore la API de base de datos:
>>> from polls.models import Question, Choice # Import the model classes we just wrote.
# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>
# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
# Save the object into the database. You have to call save() explicitly.
>>> q.save()
# Now it has an ID. Note that this might say "1L" instead of "1", depending
# on which database you're using. That's no biggie; it just means your
# database backend prefers to return integers as Python long integer
# objects.
>>> q.id
1
# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()
# objects.all() displays all the questions in the database.
>>> Question.objects.all()
<QuerySet [<Question: Question object>]>
Espere un momento. <Question: Question object>``es una representación totalmente inútil de este objeto. Vamos a solucionar esto editando el modelo ``Question
( en el archivo polls/models.py
) y añadiendo un método __str__()
tanto al modelo Question
como al modelo Choice
:
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible # only if you need to support Python 2
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
@python_2_unicode_compatible # only if you need to support Python 2
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
Es importante añadir los métodos __str__()
a sus modelos, no solo para su conveniencia al lidiar con la línea de comandos interactiva, sino también porque las representaciones de objetos se usan en todo el sitio administrativo generado automáticamente de Django.
Tenga en cuenta que estos son métodos normales de Python . Vamos a añadir un método personalizado, sólo como demostración:
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
Tenga en cuenta la adición de import datetime` y from django.utils import timezone`, para hacer referencia el módulo estándar de Python datetime
y las herramientas relacionadas con el huso horario de Django django.utils. timezone
respectivamente. Si usted no está familiarizado con el manejo de la zona horaria en Python, usted puede aprender más en la documentación de soporte de zona horaria.
Guarde estos cambios e inicie un nuevo shell interactivo Python ejecutando de nuevo`` python manage.py shell``:
>>> from polls.models import Question, Choice
# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>
# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Question matching query does not exist.
# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>
# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)
# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>
# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>
# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
Para obtener más información sobre las relaciones de modelos, consulte Accediendo a objetos relacionados. Para más información sobre cómo utilizar guiones bajos para realizar búsquedas de campo a través de la API, consulte :ref: Búsquedas de campos <field-lookups-intro>. Para más detalles sobre la API de base de datos, consulte nuestra Referencia de API de base de datos.
Presentando el sitio administrativo de Django¶
Filosofía
La generación de sitios administrativos para su personal o clientes para agregar, modificar y eliminar contenido es un trabajo aburrido que no requiere mucha creatividad. Por esa razón, Django automatiza completamente la creación de interfaces de sitios administrativos para los modelos.
Django fue escrito en un entorno de sala de redacción, con una separación muy clara entre «los editores de contenido» y el sitio «público». Los administradores del sitio utilizan el sistema para agregar noticias, eventos, resultados deportivos, etc., y ese contenido se muestra en el sitio público. Django resuelve el problema de crear una interfaz unificada para los administradores del sitio para editar el contenido.
El sitio admin no está destinado a ser utilizado por los visitantes del sitio. Es para los administradores del sitio.
Creando un usuario del admin¶
Primero tendremos que crear un usuario que pueda iniciar sesión en el sitio administrativo. Ejecute el siguiente comando:
$ python manage.py createsuperuser
Introduzca su nombre de usuario deseado y pulse enter.
Username: admin
A continuación se le solicitará su dirección de correo electrónico deseada:
Email address: admin@example.com
El paso final es introducir su contraseña. Se le pedirá que introduzca su contraseña dos veces, la segunda vez como confirmación de la primera.
Password: **********
Password (again): *********
Superuser created successfully.
Inicie el servidor de desarrollo¶
El sitio administrativo de Django se activa de forma predeterminada. Vamos a iniciar el servidor de desarrollo y a explorarlo.
Si el servidor no está en marcha, inícielo de la siguiente forma:
$ python manage.py runserver
A continuación, abra un navegador Web y vaya a «/admin/» en su dominio local, por ejemplo, http://127.0.0.1:8000/admin/. Usted debe ver la pantalla de inicio de sesión del sitio administrativo:
Dado que la traducción se activa de forma predeterminada, la pantalla de inicio de sesión puede aparecer en su propio idioma, dependiendo de la configuración del navegador y de si Django tiene una traducción para este idioma.
Acceda al sitio administrativo¶
Ahora, intente iniciar sesión con la cuenta de superusuario que creó en el paso anterior. Debería ver la página de índice del sitio administrativo de Django:
Usted debería ver algunos tipos de contenidos editables: grupos y usuarios. Ellos son proporcionados por django.contrib.auth
, el framework de autenticación enviado por Django.
Haga que la aplicación encuesta se pueda modificar en el sitio administrativo¶
Pero ¿Dónde está nuestra aplicación encuesta? No se muestra en la página de índice del sitio administrativo.
Sólo hay una cosa por hacer: tenemos que indicarle al sitio administrativo que los objetos Question
tienen una interfaz del sitio administrativo. Para ello, abra el archivo polls/admin.py
y edítelo para que se vea de la siguiente manera:
from django.contrib import admin
from .models import Question
admin.site.register(Question)
Explore la funcionalidad gratuita del sitio administrativo¶
Ahora que hemos registrado el modelo Question
, Django sabe que se debe desplegar en la página de índice del sitio administrativo:
Haga clic en «Questions». Ahora usted está en la página «lista de cambios» para las preguntas. Esta página muestra todas las preguntas de la base de datos y le permite seleccionar una para modificarla. Ahí está la pregunta «¿Qué pasa?» que creamos anteriormente:
Haga clic en la pregunta «¿Qué pasa?» para editarla:
Cosas a tener en cuenta aquí:
- El formulario se genera automáticamente a partir del modelo
Question
. - Los diferentes tipos de campos del modelo (
DateTimeField
,CharField
) corresponden al widget de entrada HTML adecuado. Cada tipo de campo sabe cómo mostrarse en el sitio administrativo de Django. - Cada
DateTimeField
tiene atajos de JavaScript sin restricciónes. Las fechas tienen un atajo «Hoy» y una ventana emergente del calendario, mientras que las horas tienen un atajo «Ahora» y una ventana emergente conveniente que enumera las horas que se registran comúnmente.
La parte inferior de la página le da un par de opciones:
- Guardar– Guarda los cambios y retorna a la página de la lista de cambios para este tipo de objeto.
- Guardar y continuar editando – Guarda los cambios y recarga la página del sitio administrativo para este objeto.
- Guardar y añadir otro – Guarda los cambios y carga un nuevo formulario vacio para este tipo de objeto.
- Eliminar – Muestra una página de confirmación de eliminación.
Si el valor de «Date published» no coincide con la hora en la que creó la pregunta en el Tutorial 1, probablemente significa que se olvidó de establecer el valor correcto para la configuración de TIME_ZONE
. Modifíquelo, recargue la página y compruebe que aparezca el valor correcto.
Modifique la «Date published» haciendo clic en los atajos «Hoy» y «Ahora». Después, haga clic en «Guardar y continuar editando». Luego haga clic en «Historial» en la parte superior derecha. Usted verá una página que enumera todos los cambios realizados a este objeto a través del sitio administrativo de Django, con el registro de tiempo y el nombre de usuario de la persona que realizó el cambio:
Cuando se sienta cómodo con la API de modelos y se haya familiarizado con el sitio administrativo, lea la parte 3 de este tutorial para aprender sobre cómo agregar más vistas a nuestra aplicación encuestas.