Kitabı oku: «Django 2», sayfa 4

Yazı tipi:

Crear plantillas para vistas

Una vez tiene las vistas y los patrones de URL de la aplicación blog, es momento de añadir las plantillas para mostrar artículos con cierta armonía.

Para ello, se va a crear la siguiente estructura de directorios y ficheros dentro de la aplicación blog:


Esta estructura contendrá las plantillas para las vistas. El fichero base.html incluirá el contenido principal de HTML, que estará dividido por el área de contenido, el menú y una barra lateral. Este contenido será reutilizado por las diferentes plantillas de forma que su edición sea más sencilla y los cambios se propaguen a lo largo de todas las vistas. Los ficheros list.html y detal.html heredarán del fichero base.html para pintar el listado artículos y la vista de detalle, respectivamente.

Django posee un lenguaje de plantillas muy potente que permite especificar los datos a mostrar. Está basado en etiquetas (template tag), variables (template variable) y filtros (template filter) de plantilla:

• Las etiquetas controlan la renderización de la plantilla y son semejantes a {% tag %}.

• Las variables son reemplazadas con valores cuando la plantilla se renderiza y se representan como {{ variable }}.

• Los filtros permiten modificar variables para ser renderizadas de forma personalizada y son {{ variable|filter }}.

Para obtener más detalles sobre los filtros y etiquetas de que dispone Django se puede visitar https://docs.djangoproject.com/en/2.0/ref/templates/builtins/.

Edite el fichero base.html para añadir el siguiente código:


{% load static %} le indica a Django que cargue la plantilla static, contenida en la aplicación django.contrib.staticfiles, el cual está definido en la variable de configuración INSTALLED_APPS. Tras cargarla, se puede utilizar el filtro {% static %} en la plantilla, el cual permite cargar contenido estático, como el fichero blog.css, alojado bajo el directorio static/ de la aplicación blog. Copie el directorio static/ del código disponible para este capítulo en la misma localización del proyecto para aplicar las hojas de estilo CSS.

También se pueden ver dos etiquetas {% block %}. Estas definen una región a Django. Las plantillas que heredan de esta plantilla base pueden incluir contenido dentro de estos bloques. Se han definido dos bloques, uno llamado title y otro content.

Edite el fichero post/list.html con el siguiente código:


Con la etiqueta {% extends %} se indica a Django que herede de la plantilla blog/base.html. De este modo, se puede redefinir el contenido de los bloques title y content de la plantilla base con otro contenido. Para esto se iteran sobre los artículos y se muestra: su título, fecha de publicación, autor y contenido, incluyendo el enlace canónico al artículo en el título. En el contenido se aplican dos filtros: truncatewords, que trunca el valor a un número específico de caracteres, y linebreaks, que convierte la salida en saltos de línea de HTML. Se pueden concatenar tantos filtros como quiera, donde cada uno será aplicado con la salida generada por el filtro anterior.

Abra el intérprete y ejecute el comando python manage.py runserver para arrancar el servidor de desarrollo. Abra en el navegador http://127.0.0.1:8000/blog/ y verá corriendo la aplicación. Recuerde que necesita algún artículo en el estado published para que pueda verlos aquí. El aspecto debería ser:


Ahora se va a editar el fichero post/detail.html:


Tras editarlo, se puede volver al navegador y pulsar sobre el enlace del título para acceder a la vista de detalle. Debería aparecer:


Si mira a la URL, verá /blog/2017/12/14/who-was-django-reinhardt/. Se han diseñado URLs para el artículo aptas para SEO.

Añadir paginación

En el momento en el que empiece a añadir contenido a el blog, pronto se dará cuenta de que es necesario dividir el listado de artículos en diferentes páginas. Django trae ya una clase capaz de realiza esta paginación. Modifique la vista post_list del fichero views.py de la aplicación blog del siguiente modo:


Así es como funciona la paginación:

1. Se instancia un objeto de la clase Paginator con el número de objetos que queremos visualizar en cada página.

2. Se obtiene el parámetro GET page que indica la página actual que se va a mostrar.

3. Se obtienen los objetos adecuados a mostrar según la página llamando al método page() de Paginator.

4. Si el parámetro page no es un entero, obtiene la primera página del listado. Si el número es mayor que la última página de resultados, obtendrá la última página.

5. Pasa el número de página y el subconjunto de artículos a la plantilla.

Ahora hay que crear una plantilla que muestre el paginador, de modo que pueda ser incluido en cualquier plantilla que lo necesite. Se va a crear una nueva plantilla dentro del directorio templates/ de la aplicación blog, añadiendo el siguiente contenido:


La plantilla del paginador espera un objeto Page para poder visualizar información de la página actual, el número total de páginas y los enlaces de página siguiente y anterior. Se vuelve a la plantilla blog/post/list.html para incluir la plantilla pagination.html al final del bloque {% content %}, del siguiente modo:


Dado que la plantilla de paginación hace uso de la variable page para paginar, así relaciona dicha variable con la que contiene los artículos en el listado de artículos. De este modo se puede reutilizar la plantilla de paginación para cualquier otro modelo.

Si va al navegador y visita http://127.0.0.1:8000/blog/, debería ver la paginación al final del listado de artículos y los enlaces de navegación.


Usar vistas basadas en clase

Las vistas de tipo basadas en clase son una alternativa para implementar vistas como objetos Python en vez de funciones. Mientras que una vista es un elemento al que se puede llamar y que toma una solicitud web y devuelve una respuesta, también se pueden definir vistas como métodos de clase. Django aporta clases base para poder hacerlo de forma sencilla. Todas ellas heredan de la clase View, la cual interactúa con el envío y recepción de contenido HTTP y otras funcionalidades comunes.

Las vistas basadas en clase ofrecen algunas ventajas frente a las vistas de función:

• Permiten organizar el código según métodos HTTP, como GET, POST o PUT, en métodos de clase separados, en vez de usar sentencias condicionales.

• Permiten utilizar herencia múltiple para crear vistas reutilizables (también conocidas como mixins).

Para obtener más información, la documentación de Django ofrece una introducción a las vistas basadas en clase en https://docs.djangoproject.com/en/2.0/topics/class-based-views/intro/.

Se va a cambiar la vista post_list para que funcione como una vista basada en clase usando la clase ListView de Django. Esta clase permite listas de objetos de cualquier tipo.

Edite el fichero views.py de la aplicación blog y añada las siguientes líneas:


Esta vista basada en clase es análoga a la vista previa post_list. En el código anterior ha especificado a ListView lo siguiente:

• Utiliza un QuerySet específico en vez de utilizar el que devuelve todos los objetos. En vez de definir el atributo queryset, podría haber especificado model = Post y Django hubiera construido el QuerySet genérico Post.objects.all() por usted.

• El nombre de la variable de contexto que contiene todos los elementos es posts. Si no se especifica nada, el nombre por defecto es object_list.

• Que cada página contenga tres elementos.

• La plantilla que debe utilizar para renderizar la página, sino ListView utilizará la plantilla por defecto blog/post_list.html.

Queda por modificar el fichero urls.py de la aplicación blog. Comente el patrón de post_list y añada un nuevo patrón de URL para la clase PostListView del siguiente modo:


Para poder mantener la paginación en funcionamiento, es necesario pasar a la plantilla el objeto de página correcto. La vista genérica ListView de Django pasa la página seleccionada en una variable llamada page_obj, por lo que hay que editar la plantilla post/list.html de acuerdo con dicho nombre. Para ello realizará la siguiente modificación:


Para verificar que todo funciona correctamente del mismo modo que lo hacía la vista post_list, abra http://127.0.0.1:8000/blog/ en el navegador. Este es un ejemplo sencillo de una vista basada en clase que utiliza una clase genérica provista por Django. Se profundizará más sobre vistas basadas en clase en el capítulo 10, Construir una plataforma E-Learning, y en capítulos sucesivos.

Resumen

En este capítulo se han descrito los elementos básicos de Django para la creación de una aplicación tipo blog. Se han diseñado los modelos de datos, aplicando migraciones al proyecto. También se han creado las vistas, plantillas y patrones de URL necesarios para el blog, incluyendo la paginación.

En el siguiente capítulo se describe cómo mejorar el blog con un sistema de comentarios y etiquetado y permitir a los usuarios compartir artículos por email.

2
Funciones avanzadas del blog

En el capítulo anterior creó una aplicación sencilla tipo blog. En este capítulo se mejorará la aplicación con funcionalidades avanzadas como compartir artículos por email, añadir comentarios, etiquetar artículos y recuperar artículos por semejanza. En este capítulo se tratarán los siguientes puntos:

• Envío de emails con Django.

• Creación y gestión de formularios en vistas.

• Creación de formularios a partir de modelos de datos.

• Integración con aplicaciones de terceros.

• Construcción de QuerySets complejos.

Compartir artículos por email

Lo primero que se hará será permitir que los usuarios compartan artículos enviando un correo electrónico. Piense cómo podría usar las vistas, los patrones de URL y las plantillas para crear esta funcionalidad con lo que aprendió en el capítulo anterior. Ahora, se detallará qué necesita para permitir a los usuarios enviar artículos por email:

• Crear un formulario para los usuarios para rellenar su nombre y correo electrónico, el correo del destinatario y un comentario, como campo opcional.

• Crear una vista en el fichero views.py que gestione los datos y envíe el email.

• Añadir un patrón de URL para la nueva vista en el fichero urls.py de la aplicación blog.

• Crear una plantilla para visualizar el formulario.

Crear formularios en Django

A continuación, se describe cómo elaborar un formulario para compartir artículos. Django tiene un sistema de formularios con el que crear formularios web de una manera sencilla. Este sistema permite definir los campos del formulario, el modo en que se visualizan y la forma de validación de la entrada de datos. Con este sistema, Django ofrece una forma sencilla y flexible de visualizar formularios y gestionar datos.

Django incluye dos clases base para la elaboración de formularios:

• Form, que permite construir un formulario estándar.

• ModelForm, que permite construir un formulario a partir de una instancia de modelo de datos.

Primero cree el fichero forms.py dentro del directorio blog de la aplicación con el siguiente contenido:


Este es el primer formulario de Django. La clase que ha creado hereda de la clase base Form, donde se definen diferentes atributos con tipos específicos, encargados de la validación de los campos.

Los formularios pueden declararse en cualquier lugar de un proyecto Django. Por convención, el lugar definido para ellos es el fichero forms.py de cada aplicación.

El tipo del campo name es CharField. Este tipo de campo se renderiza como <input type=”text”> en código HTML. Cada tipo de campo tiene una representación HTML (o widget) asociada, que puede ser redefinida a través del parámetro widget. En el caso del campo comments, el widget definido es de tipo Textarea que quedará renderizado como <textarea> en HTML en lugar de <input>.

La validación de campos depende del tipo de campo definido. Por ejemplo, los campos email y to son campos del tipo EmailField. Ambos campos requieren una dirección válida de correo electrónico; en caso contrario, la validación de campos provocará una excepción de tipo forms.ValidationError y el formulario no podrá ser validado. Otros parámetros se tienen en cuenta a la hora de realizar la validación: hay un número máximo de caracteres definidos en el campo name, y también se especifica que el campo comments no es obligatorio. Todos estos parámetros se tienen en cuenta a la hora de realizar las validaciones. El tipo de campos que ha usado son solo una pequeña muestra de los que Django dispone. Puede encontrar información sobre todos los campos de formulario disponibles en https://docs.djangoproject.com/en/2.0/ref/forms/fields/.

Usar formularios en vistas

Ahora va a crear una nueva vista que gestione el formulario y el envío de email, siempre y cuando contenga información válida. Para ello editará el fichero views.py de la aplicación blog y añadirá el siguiente contenido:



Esta vista funciona del siguiente modo:

• Se define una vista llamada post_share que recibe un objeto request y un parámetro post_id.

• Haciendo uso del atajo get_object_or_404() se recupera el artículo por identificador y por estado published.

• Usará la misma vista para visualizar el formulario inicial y procesar la información enviada. Se identifica si el formulario ha sido enviado mediante el atributo method del objeto request. El formulario se envía por el método POST. Si se recibe una solicitud GET, se genera un formulario vacío. Si se recibe una petición POST, se debe procesar la información del formulario. Por este motivo, utilizará la sentencia condicional request.method == 'POST' para distinguir entre ambos escenarios.

Los siguientes pasos corresponden al procesamiento del formulario:

1. Cuando la vista se carga inicialmente con una solicitud GET, se crea una nueva instancia de formulario que se mostrará vacía en la plantilla HTML.


2. El usuario rellena el formulario y lo envía por método POST. En ese momento, se crea una instancia de formulario con los datos enviados contenidos en request.POST:


3. Después de esto se validan los datos enviados usando el método is_valid() del formulario. Este método validará la información introducida en el formulario y devolverá True si todos los campos contienen datos válidos. Si al menos uno de los campos no hubiera podido validarse, el método devolverá False. A partir de entonces, la lista de errores de validación estará accesible en form.errors.

4. Si el formulario no es válido, se renderizará la plantilla de nuevo, con la información enviada, mostrando un mensaje de error en las validaciones que hubiesen fallado.

5. Si el formulario es válido, se recuperarán los datos validados a través de form.claened_data. Este atributo es de tipo diccionario, donde las claves son los nombres de los campos del formulario.

Si el formulario no es válido, cleaned_data solo contendrá los campos válidos.

A continuación se describe cómo se envían correos electrónicos con Django para completar la funcionalidad.

Enviar emails con Django

Enviar emails con Django es una acción muy directa. Primero hay que disponer de un servidor SMTP local o definir uno externo en la configuración, incluyendo la siguiente información en el fichero de configuración settigns.py del proyecto:

• EMAIL_HOST es el nombre donde se aloja el servidor SMTP. Por defecto es localhost.

• EMAIL_PORT es el puerto del SMTP. Por defecto es 25.

• EMAIL_HOST_USER es el usuario del servidor SMTP.

• EMAIL_HOST_PASSWORD es la contraseña de usuario del servidor SMTP.

• EMAIL_USE_TLS indica si debe usar la conexión segura sobre TLS.

• EMAIL_USE_SSL indica si usar una conexión TLS implícita.

Si no dispone de un servidor SMTP, puede indicar a Django que escriba los emails en la consola, a través de la siguiente línea en la configuración:


Con esta configuración, Django escribirá todos los emails a través del intérprete. Esta opción es útil para tareas de validación de la aplicación sin disponer de un servidor SMTP.

Si lo que quiere es enviar emails, pero no dispone de un servidor SMTP local, puede usar la configuración del servidor SMTP del proveedor de servicio de email. Por ejemplo, la siguiente configuración es válida para enviar correos electrónicos a través de los servidores de Gmail con una cuenta de Google:


Ejecute el comando python manage.py shell para abrir un intérprete de Python y enviar un email del siguiente modo:


La función send_mail() recoge el asunto, el mensaje, el remitente y una lista de los destinatarios como argumentos necesarios. Entre los argumentos opcionales existe fail_silently=False, que permite no elevar excepciones en caso de no poder mandar correctamente el email. Como salida se obtiene el número de emails enviados correctamente, por lo que si la salida obtenida es 1, entonces el email ha sido enviado.

Si envía emails con Gmail con la configuración anterior, hay que tener en cuenta activar el acceso para aplicaciones menos seguras en https://myaccount.google.com/lesssecureapps del siguiente modo:


Ahora, va a incorporar la funcionalidad dentro de la vista.

Para ello va a editar la vista post_share en el fichero views.py de la aplicación de blog:


Ha declarado una variable sent y la ha inicializado a True cuando el artículo se envía. Esta variable la usará más tarde para mostrar un mensaje en la plantilla, indicando que el formulario se ha enviado correctamente. Dada la necesidad de incluir en el correo un enlace al artículo, es necesario recuperar la ruta absoluta con el método get_absolute_url(). Se usa esta ruta como parámetro de entrada para request.build_absolute_uri(), construyendo una URL completa, incluyendo el esquema HTTP y nombre de dominio. Para construir el asunto y el cuerpo del mensaje se utilizan los datos procesados del formulario, una vez validado, y, por último, se envía el correo a la dirección estipulada en el campo to del formulario.

Ahora que la vista está completa, recuerde que es necesario añadir un nuevo patrón de URL. Para ello habrá que editar el fichero urls.py de la aplicación blog e incluir el patrón para la vista post_share:


Renderizar formularios en plantillas

Después de haber creado el formulario, programado la vista y añadido el patrón de URL, solo falta la plantilla de la vista. Para ello va a crear un nuevo fichero dentro de la ruta blog/templates/blog/post/ llamado share.html con el siguiente contenido:


Esta es la plantilla encargada de mostrar el formulario o un mensaje en caso de haber podido mandar el email. Como se puede observar, ha creado el elemento de formulario para que sea enviado por el método POST:


Después, le sigue la instancia del formulario. Le indicará a Django que renderice los campos en HTML con modo párrafo, es decir, con elementos <p> a través del método as_p. También puede mostrar el formulario como una lista de elementos utilizando as_ul, o como una tabla, a través del método as_table. Si quiere renderizar cada campo, puede iterar sobre cada uno de ellos del siguiente modo:


La etiqueta de plantilla {% csrf_token %} introduce un campo oculto con un token autogenerado para evitar ataques de tipo Cross-Site Request Forgery (CSRF). Este ataque consiste en un programa o sitio web malicioso realizando acciones no deseadas en nombre de un usuario en su sitio web. Se puede obtener más información en https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF).

La etiqueta mencionada genera un campo oculto con un código similar al siguiente:


Por defecto, Django verifica el token CSRF en todas las solicitudes tipo POST. Es importante recordar la inclusión de las etiquetas csrf_token en todos los formularios enviados vía POST.

Va a modificar la plantilla blog/post/detail.html y añadir el siguiente link para compartir la URL del artículo después de la variable {{ post.body | linebreaks }}:


Es necesario recordar que está construyendo URLs de forma dinámica usando la etiqueta {% url %} ofrecida por Django. Está utilizando el espacio de nombres blog y la URL post_share, y se pasa como parámetro el identificador del artículo para conformar la URL completa.

Va a revisar lo que ha realizado arrancando el servidor de desarrollo con python manage.py runserver y abriendo la URL http://127.0.0.1:8000/blog/ en el navegador. Seleccione cualquier título de artículo para visitar el detalle. Bajo el contenido del artículo, debería ver el enlace que ha añadido como se aprecia en las imágenes:


Si pincha en el enlace Share this post, le redirige a la página que incluye el formulario de compartición vía email de artículos.


Los estilos CSS para el formulario están incluidos en el código de ejemplo en el fichero static/css/blog.css. Tras seleccionar el botón Send e-mail, el formulario se envía y valida. Si todos los campos contienen información válida, obtendrá un mensaje de confirmación como este:


Si la información de entrada no es válida, el formulario se vuelve a visualizar incluyendo los errores de validación:


Hay que tener en cuenta que los navegadores modernos evitan el envío de información errónea o vacía. Esto se debe a que el navegador realiza una validación previa en base al tipo de campo y sus restricciones. En este caso, el formulario no será enviado y el formulario mostrará sus propios mensajes de error para los campos incorrectos.

El formulario para compartir artículos vía email está terminado. Lo siguiente es crear un sistema de comentarios para el blog.

₺962

Türler ve etiketler

Yaş sınırı:
0+
Hacim:
1026 s. 1145 illüstrasyon
ISBN:
9788426728661
Yayıncı:
Telif hakkı:
Bookwire
İndirme biçimi:
Metin
Средний рейтинг 0 на основе 0 оценок
Metin PDF
Средний рейтинг 0 на основе 0 оценок
Metin
Средний рейтинг 0 на основе 0 оценок
Metin
Средний рейтинг 0 на основе 0 оценок
Metin PDF
Средний рейтинг 0 на основе 0 оценок
Metin PDF
Средний рейтинг 0 на основе 0 оценок
Metin PDF
Средний рейтинг 0 на основе 0 оценок
Metin PDF
Средний рейтинг 3,8 на основе 6 оценок
Metin PDF
Средний рейтинг 0 на основе 0 оценок
Metin PDF
Средний рейтинг 0 на основе 0 оценок
Metin
Средний рейтинг 4 на основе 1 оценок