diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
commit | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (patch) | |
tree | 0dd8b084480983cf9f9680e8aedb92782a921b13 /files/es/learn/server-side/django/authentication | |
parent | 4b1a9203c547c019fc5398082ae19a3f3d4c3efe (diff) | |
download | translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.gz translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.bz2 translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.zip |
initial commit
Diffstat (limited to 'files/es/learn/server-side/django/authentication')
-rw-r--r-- | files/es/learn/server-side/django/authentication/index.html | 714 |
1 files changed, 714 insertions, 0 deletions
diff --git a/files/es/learn/server-side/django/authentication/index.html b/files/es/learn/server-side/django/authentication/index.html new file mode 100644 index 0000000000..af07915ad9 --- /dev/null +++ b/files/es/learn/server-side/django/authentication/index.html @@ -0,0 +1,714 @@ +--- +title: 'Tutorial de Django Parte 8: Autenticación y permisos de Usuario' +slug: Learn/Server-side/Django/Authentication +tags: + - Aprender + - Artículo + - Autenticacion de Django + - Autenticación + - Principiante + - Python + - Sesiones + - Tutorial + - django autenticación + - permisos +translation_of: Learn/Server-side/Django/Authentication +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}</div> + +<p class="summary">En este tutorial mostraremos cómo permitir a los usuarios iniciar sesión en tu sitio con sus propias cuentas, y cómo controlar lo que pueden hacer basándose en si han iniciado sesión o no y sus <em>permisos</em>. Como parte de esta demostración extenderemos el sitio web de la <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website" style="font-size: 1.25rem;">BibliotecaLocal</a>, añadiendo páginas de inicio y cierre de sesión, y páginas específicas de usuarios y personal de la biblioteca para ver libros que han sido prestados.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisitos:</th> + <td>Completa todos los temas del tutorial anterior, incluyendo: <a href="/en-US/docs/Learn/Server-side/Django/Sessions">Django Tutorial Part 7: Sessions framework</a>.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Comprender como configurar y usar la autenticación de usuario y los permisos.</td> + </tr> + </tbody> +</table> + +<h2 id="Introducción">Introducción</h2> + +<p>Django proporciona un sistema de autenticación y autorización ("permisos"), construido sobre el framework de sesión discutido en el <a href="/en-US/docs/Learn/Server-side/Django/Sessions">tutorial anterior</a>, que le permite verificar credenciales de usuario y definir que acciones puede realizar cada usuario. El framework incluye modelos para <code>Users</code> y <code>Groups</code> (una forma genérica de aplicar permisos a más de un usuario a la vez), permisos/indicadores (permissions/flags) que designan si un usuario puede realizar una tarea, formularios y vistas para iniciar sesión en los usuarios, y view tools para restringir el contenido.</p> + +<div class="note"> +<p><strong>Nota</strong>: Según Django el sistema de autenticación pretende ser muy genérico, y, por lo tanto, no proporciona algunas características proporcinadas en otros sistemas de autenticación web. Las soluciones para algunos problemas están disponibles como paquetes de terceros. Por ejemplo, regulación de intentos de inicio de sesión y autenticación frente a terceros (por ej. OAuth).</p> +</div> + +<p>En este tutorial mostraremos cómo habilitar la autenticación de usuarios en el sitio web <a href="https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Tutorial_local_library_website">BibliotecaLocal</a>, crear tus propias páginas de login y logout, añadir permisos a tus modelos, y controlar el acceso a las páginas. Usaremos la autenticación/permisos para desplegar listas de libros que han sido solicitados tanto por los usuarios como por los bibliotecarios.</p> + +<p>El sistema de autenticación es muy flexible, y puedes crear tus URLs, formularios, vistas y plantillas desde el inicio si quieres, simplemente llamando a la API provista para loguear al usuario. Sin embargo, en este artículo vamos a usar las vistas y formularios de autenticación "en stock" de Django para nuestras páginas de login y logout. De todos modos necesitaremos crear algunas plantillas, pero eso es bastante fácil.</p> + +<p>Te mostraremos también cómo crear permisos, y revisar el estado de login y permisos tanto en vistas como en plantillas.</p> + +<h2 id="Habilitanto_la_autenticación">Habilitanto la autenticación</h2> + +<p>La autenticación fue habilitada automáticamente cuando <a href="/es/docs/Learn/Server-side/Django/skeleton_website">creamos el sitio web esqueleto</a> (en el tutorial 2), así que no necesitas hacer nada más en este punto.</p> + +<div class="note"> +<p><strong>Nota</strong>: Toda la configuración necesaria fue hecha por nosotros cuando creamos la aplicación usando el comando <code>django-admin startproject</code>. Las tablas de base de datos para los usuarios y permisos de modelo fueron creados la primera vez que ejecutamos <code>python manage.py migrate</code>.</p> +</div> + +<p>La configuración se establece en las secciones <code>INSTALLED_APPS</code> y <code>MIDDLEWARE</code> del archivo del proyecto (<strong>locallibrary/locallibrary/settings.py</strong>), como se muestra abajo:</p> + +<pre class="brush: python notranslate">INSTALLED_APPS = [ + ... +<strong> 'django.contrib.auth', </strong>#Core authentication framework and its default models. +<strong> 'django.contrib.contenttypes', #</strong>Django content type system (allows permissions to be associated with models). + .... + +MIDDLEWARE = [ + ... +<strong> 'django.contrib.sessions.middleware.SessionMiddleware',</strong> #Manages sessions across requests + ... +<strong> 'django.contrib.auth.middleware.AuthenticationMiddleware',</strong> #Associates users with requests using sessions. + .... +</pre> + +<h2 id="Creando_usuarios_y_grupos">Creando usuarios y grupos</h2> + +<p>Ya creaste tu primer usuario cuando revisamos el <a href="/es/docs/Learn/Server-side/Django/Admin_site">sitio de administración de Django</a> en el tutorial 4 (fue un superusuario, creado con el comando <code>python manage.py createsuperuser</code>). Nuestro superusuario ya está autenticado y tiene todos los permisos, así que necesitaremos crear un usuario de prueba que represente un usuario normal del sitio. Estaremos usando el sitio de administración para crear los grupos y logins de nuestro sitio web <em>BibliotecaLocal</em>, ya que es una de las formas más rápidas de hacerlo.</p> + +<div class="note"> +<p><strong>Nota</strong>: Puedes también crear usuarios mediante programación, como se muestra abajo. Tendrías que hacerlo, por ejemplo, si estuvieras desarrollando una interfaz para permitir a los usuarios crear sus propios logins (no deberías dar a los usuarios acceso al sito de administración).</p> + +<pre class="brush: python notranslate">from django.contrib.auth.models import User + +# Create user and save to the database +user = User.objects.create_user('myusername', 'myemail@crazymail.com', 'mypassword') + +# Update fields and then save again +user.first_name = 'John' +user.last_name = 'Citizen' +user.save() + +</pre> +</div> + +<p>A continuación, primero crearemos un grupo y luego un usuario. Aunque no tengamos ningún permiso aún para otorgar a los miembros de nuestra biblioteca, si lo necesitamos para más adelante, será mucho más fácil otorgarlo una vez al grupo que individualmente a cada miembro.</p> + +<p>Inicia el servidor de desarrollo y navega hasta el sitio de administracion en tu navegador web local (<a href="http://127.0.0.1:8000/admin/">http://127.0.0.1:8000/admin/</a>). Ingresa al sitio usando las credenciales de la cuenta de tu superusuario. El nivel superior del sitio de administracion "Admin site" muestra todos tus modelos, ordenados por la aplicacion por defecto de Django "django application". Desde la seccion de <strong>Autenticación y Autorización </strong>puedes dar click en los enlaces de <strong>Usuarios </strong>"Users" y <strong>Grupos </strong>"Groups" para ver todos sus registros existentes.</p> + +<p><img alt="Admin site - add groups or users" src="https://mdn.mozillademos.org/files/14091/admin_authentication_add.png" style="border-style: solid; border-width: 1px; display: block; height: 364px; margin: 0px auto; width: 661px;"></p> + +<p>Primero vamos a crear un nuevo grupo para los miembros de nuestra biblioteca.</p> + +<ol> + <li>Da click en el boton <strong>Add </strong>"Añadir" (Enseguida de Group) para crear un nuevo grupo ; ingresa el <strong>Nombre </strong>"Name" para el grupo de "Library Members".<img alt="Admin site - add group" src="https://mdn.mozillademos.org/files/14093/admin_authentication_add_group.png" style="border-style: solid; border-width: 1px; display: block; height: 561px; margin: 0px auto; width: 800px;"></li> + <li>No necesitamos de ningun permiso para el grupo , entonces solo presiona Save (Seras redirigido a una lista de los grupos disponibles).</li> +</ol> + +<p>Ahora vamos a crear un usuario:</p> + +<ol> + <li>Navega de vuelta a la pagina de inicio "home" del sitio de administracion "Admin site".</li> + <li>Da click en el boton <strong>Add </strong>"Añadir" que queda enseguida de Users "Usuarios" para abrir el cuadro de dialogo de Usuario <strong>Add </strong>"Añadir usuario".<img alt="Admin site - add user pt1" src="https://mdn.mozillademos.org/files/14095/admin_authentication_add_user_prt1.png" style="border-style: solid; border-width: 1px; display: block; height: 409px; margin: 0px auto; width: 800px;"></li> + <li>Ingresa un <strong>Nombre de Usuario </strong>"Username", <strong>Contraseña </strong>"Password" y <strong>Confirmacion de Contraseña</strong> "Password confirmation" apropiado para tu usuario de prueba.</li> + <li>Presiona <strong>Save </strong>"Guardar" para crear el usuario.<br> + <br> + El sitio de administrador creara el nuevo usuario e inmediatamente te llevara a la pantalla de <em>Change user </em>"Cambios del usuario" donde puedes cambiar tu <strong>nombre de usuario</strong> "Username" y agregar informacion para los campos opcionales del modelo de Usuario "User". Estos campos incluyen el primer nombre "first name", el apellido "last name", la direcion de correo electronico "email adress", los estados de los usuarios y sus permisos "users status and permissions" (solo el indicador <strong>Active </strong>"Activo" deberia ser activado). Mas abajo puedes especificar los grupos y permisos del usuario, y ver datos importantes relacionados a el usuario (ej: la fecha en que se agrego y la fecha del ultimo inicio de sesion)</li> + <li><img alt="Admin site - add user pt2" src="https://mdn.mozillademos.org/files/14097/admin_authentication_add_user_prt2.png" style="border-style: solid; border-width: 1px; display: block; height: 635px; margin: 0px auto; width: 800px;"></li> + <li>En la seccion <em>Groups</em> "Grupos", selecciona el grupo <strong>Library Member</strong> de la lista de grupos disponibles, y entonces presiona la <strong>la flecha apuntando a la derecha </strong>entre las dos cajas para moverlo dentro de la caja de <em>Chosen groups </em>"Grupos seleccionados".<img alt="Admin site - add user to group" src="https://mdn.mozillademos.org/files/14099/admin_authentication_user_add_group.png" style="border-style: solid; border-width: 1px; display: block; height: 414px; margin: 0px auto; width: 933px;"></li> + <li>Aqui no necesitamos hacer nada adicional, entonces de nuevo solo seleciona <strong>SAVE</strong> "Guardar", para ir a la lista de usuarios.</li> +</ol> + +<p>¡Esta hecho! Ahora tienes la cuenta de un miembro normal de la libreria, el cual estara disponible para ser usado en tus pruebas (una vez que hayamos implementado las paginas para permitirles iniciar sesion).</p> + +<div class="note"> +<p><strong>Nota</strong>: Deberias intentar crear otro usuario miembro de <em>library. </em>Al igual que un grupo para los bibliotecarios <em>"Librarians", </em>¡y agregar usuarios a este tambien! </p> +</div> + +<h2 id="Configurando_nuestras_vistas_de_autenticación">Configurando nuestras vistas de autenticación</h2> + +<p>Django provee todo lo necesario para crear las páginas de autenticación para manejar inicio y cierre de sesión y gestión de contraseñas "fuera de la caja". Esto incluye un mapeador de URL, vistas "views" y formularios "forms", pero no incluye las plantillas "templates", ¡Tenemos que crear las nuestras!</p> + +<p>En esta sección, mostramos cómo integrar el sistema por defecto en el sitio web de <em>BibliotecaLocal </em>y crear plantillas "templates". Las incluiremos en las URLs principales del proyecto.</p> + +<div class="note"> +<p><strong>Nota</strong>: No tienes que usar nada de este código, pero es probable que quieras hacerlo porque hace las cosas mucho más fáciles. Seguramente necesitará cambiar el código de manejo de formularios si cambia su modelo de usuario (¡un tema avanzado!) pero aun asi, todavía podrá usar las funciones de vista de stock.</p> +</div> + +<div class="note"> +<p><strong>Nota: </strong>En este caso podríamos razonablemente poner las páginas de autenticación, incluyendo las direcciones URL y plantillas, dentro de nuestra aplicación de catálogo. Sin embargo, si tuviéramos varias aplicaciones, sería mejor separar este comportamiento de inicio de sesión compartido y tenerlo disponible en todo el sitio, ¡así que eso es lo que hemos mostrado aquí!</p> +</div> + +<h3 id="URLs_del_proyecto">URL's del proyecto</h3> + +<p>Añade el siguiente codigo al final del archivo url.py del proyecto (<strong>locallibrary/locallibrary/urls.py</strong>) :</p> + +<pre class="brush: python notranslate">#Add Django site authentication urls (for login, logout, password management) +urlpatterns += [ + path('accounts/', include('django.contrib.auth.urls')), +] +</pre> + +<p>Navega hasta la URL <a href="http://127.0.0.1:8000/accounts/">http://127.0.0.1:8000/accounts/</a> (¡Nota la barra inclinada hacia adelante!) y Django mostrara un error, diciendo que no puede encontrar esta URL, y listando todas las URL's que ha intentado. Aqui puedes ver las URL's que funcionaran, por ejemplo:</p> + +<div class="note"> +<p><strong>Nota: </strong>Usando el metodo anterior, añade las siguientes URL's con sus respectivos nombres entre corchetes, los cuales pueden ser usados para revertir "reverse" el mapeado de las URL's. No necesitas implementar nada mas, el anterior mapeado de URL's asigna automaticamente las mencionadas URL's.</p> +</div> + +<div class="note"> +<pre class="brush: python notranslate">^accounts/login/$ [name='login'] +^accounts/logout/$ [name='logout'] +^accounts/password_change/$ [name='password_change'] +^accounts/password_change/done/$ [name='password_change_done'] +^accounts/password_reset/$ [name='password_reset'] +^accounts/password_reset/done/$ [name='password_reset_done'] +^accounts/reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$ [name='password_reset_confirm'] +^accounts/reset/done/$ [name='password_reset_complete']</pre> +</div> + +<p>Ahora intenta navegar a la URL de inicio de sesion "login"(<a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a>). Esto fallara de nuevo, pero ahora con un error diciendote que no encuentra la plantilla "template" requerida (<strong>registration/login.html</strong>) por el buscador de directorios de plantillas . Veras el las siguientes lineas en la seccion amarilla en la parte superior:</p> + +<pre class="brush: python notranslate">Exception Type: TemplateDoesNotExist +Exception Value: <strong>registration/login.html</strong></pre> + +<p>El siguiente paso es crear un directorio de registro en la busqueda de directorios y entonces agregar el archivo <strong>login.html.</strong></p> + +<h3 id="Directorio_de_plantilla_template">Directorio de plantilla "template"</h3> + +<p>Las URL's (y vistas "views" implicitas) que recien hemos añadido esperan encontrar sus plantillas "templates" asociadas en un directorio "<strong>/registration/"</strong> en algún lugar de la ruta de búsqueda de plantillas</p> + +<p>Para este sitio pondremos nuestra pagina HTML en el directorio <strong>"templates/registration/". </strong>Este directorio debera estar en el directorio raiz de tu proyecto, es decir, el mismo directorio de las carpetas donde estan <strong>catalog </strong>y <strong>locallibrary</strong>. Por favor ahora crea las carpetas "templates" y dentro de esta "registration".</p> + +<div class="note"> +<p><strong>Note:</strong> Your folder structure should now look like the below:<br> + locallibrary (django project folder)<br> + |_catalog<br> + |_locallibrary<br> + |_templates <strong>(new)</strong><br> + |_registration</p> +</div> + +<p>Para hacer estos directorios visibles al cargador de plantillas (es decir introducir este directorio en el buscador de directorios de plantillas) abre el archivo de configuracion del proyecto setting.py (<strong>/locallibrary/locallibrary/settings.py)</strong>, y actualiza la seccion de <strong>TEMPLATES </strong>con la linea <strong>'DIRS'</strong> como se muestra a continuacion.</p> + +<pre class="brush: python notranslate">TEMPLATES = [ + { + ... +<strong> 'DIRS': ['./templates',],</strong> + 'APP_DIRS': True, + ... +</pre> + +<h3 id="Plantilla_inicio_de_sesión_login">Plantilla inicio de sesión "login"</h3> + +<div class="warning"> +<p><strong>Importante</strong>: Las plantillas de autenticacion provista en este articulo son versiones muy basicas y ligeramete modificadas de las plantillas de inicio de sesion de demostracion de Django. ¡Necesitas personalizarlos para tus propios usos!</p> +</div> + +<p>Crea un nuevo archivo HTML llamado /<strong>locallibrary/templates/registration/login.html</strong>. suministrado en el siguiente contenido :</p> + +<pre class="brush: html notranslate">{% extends "base_generic.html" %} + +{% block content %} + +{% if form.errors %} +<p>Your username and password didn't match. Please try again.</p> +{% endif %} + +{% if next %} + {% if user.is_authenticated %} + <p>Your account doesn't have access to this page. To proceed, + please login with an account that has access.</p> + {% else %} + <p>Please login to see this page.</p> + {% endif %} +{% endif %} + +<form method="post" action="{% url 'login' %}"> +{% csrf_token %} + +<div> + <td>\{{ form.username.label_tag }}</td> + <td>\{{ form.username }}</td> +</div> +<div> + <td>\{{ form.password.label_tag }}</td> + <td>\{{ form.password }}</td> +</div> + +<div> + <input type="submit" value="login" /> + <input type="hidden" name="next" value="\{{ next }}" /> +</div> +</form> + +{# Assumes you setup the password_reset view in your URLconf #} +<p><a href="{% url 'password_reset' %}">Lost password?</a></p> + +{% endblock %}</pre> + +<p id="sect1">Estas plantillas comparten algunas similitudes con algunas que hemos visto antes — extiende nuestra plantilla base y sobreescribe el bloque <code>content</code>. El resto del código es un código de manejo de formularios bastante estándar, que trataremos en un tutorial posterior. Todo lo que necesitas saber por ahora es que esto mostrará un formulario en el que puedes introducir tu usuario y contraseña, y que si introduces valores inválidos se te pedirá que ingreses los valores correctos cuando la página refresque.</p> + +<p>Navega de vuelta a la página de inicio sesión (<a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a>) una vez que hayas guardado tu plantilla, y deberías ver algo como esto:</p> + +<p><img alt="Library login page v1" src="https://mdn.mozillademos.org/files/14101/library_login.png" style="border-style: solid; border-width: 1px; display: block; height: 173px; margin: 0px auto; width: 441px;"></p> + +<p>Si intentas iniciar sesión tendrá éxito y serás redirigido a otra página (por defecto será <a href="http://127.0.0.1:8000/accounts/profile/">http://127.0.0.1:8000/accounts/profile/</a>). El problema aquí es que, por defecto, Django espera que después de iniciar sesión seas llevado a una página de perfil (que podrá ser el caso o no). Como no has definido esta página todavía, ¡obtendrás otro error!</p> + +<p>Abre la configuración del proyecto (<strong>/locallibrary/locallibrary/settings.py</strong>) y añade al final el texto de abajo. Ahora cuando inicies sesión deberías ser redirigido a la página de inicio por defecto.</p> + +<pre class="brush: python notranslate"># Redirect to home URL after login (Default redirects to /accounts/profile/) +LOGIN_REDIRECT_URL = '/' +</pre> + +<h3 id="Plantilla_cierre_de_sesión_logout">Plantilla cierre de sesión "logout"</h3> + +<p>Si navegas a la url de cierre de sesión (<a href="http://127.0.0.1:8000/accounts/logout/">http://127.0.0.1:8000/accounts/logout/</a>) verás un extraño comportamiento — tu usuario cerrará la sesión, pero serás llevado a la página de cierre de sesión del <strong>Administrador</strong>. Eso no es lo que quieres, aunque sólo sea porque el enlace de inicio de sesión de esa página te lleva a la pantalla del inicio de sesión del Administrador (y eso sólo está disponible a los usuarios que tienen el permiso <code>is_staff</code>).</p> + +<p>Crea y abre el fichero /<strong>locallibrary/templates/registration/logged_out.html</strong>. Copia en él el siguiente texto:</p> + +<pre class="brush: html notranslate">{% extends "base_generic.html" %} + +{% block content %} +<p>Logged out!</p> + +<a href="{% url 'login'%}">Click here to login again.</a> +{% endblock %}</pre> + +<p>Esta plantilla es muy simple. Tan sólo muestra un mensaje informándote que has cerrado sesión, y provee un enlace que puedes pulsar para volver a la página de inicio de sesión. Si vas a la url de cierre de sesión otra vez, deberías ver esta página:</p> + +<p><img alt="Library logout page v1" src="https://mdn.mozillademos.org/files/14103/library_logout.png" style="border-style: solid; border-width: 1px; display: block; height: 169px; margin: 0px auto; width: 385px;"></p> + +<h3 id="Plantillas_de_reinicio_de_contraseña_Password_reset">Plantillas de reinicio de contraseña "Password reset"</h3> + +<p>El sistema de reinicio de contraseña usa el correo electrónico para enviar al usuario un enlace de reinicio. Necesitas crear formularios para obtener la dirección de correo electrónico del usuario, enviar el correo, permitirle introducir una nueva contraseña y tenerla en cuenta cuando todo el proceso se haya completado.</p> + +<p>Las siguientes plantillas pueden usarse como un punto de partida.</p> + +<h4 id="Formulario_de_reinicio_de_contraseña">Formulario de reinicio de contraseña</h4> + +<p>Este es el formulario para obtener la dirección del correo electrónico del usuario (para enviar el correo de reinicio de contraseña). Crea <strong>/locallibrary/templates/registration/password_reset_form.html</strong>, y establece el siguiente contenido:</p> + +<pre class="brush: html notranslate">{% extends "base_generic.html" %} +{% block content %} + +<form action="" method="post">{% csrf_token %} + {% if form.email.errors %} \{{ form.email.errors }} {% endif %} + <p>\{{ form.email }}</p> + <input type="submit" class="btn btn-default btn-lg" value="Reset password" /> +</form> + +{% endblock %} +</pre> + +<h4 id="Reinicio_de_contraseña_hecho">Reinicio de contraseña hecho</h4> + +<p>Este formulario es mostrado después de que tu dirección de correo electrónico haya sido recogida. Crea <strong>/locallibrary/templates/registration/password_reset_done.html</strong>, y establece el siguiente contenido:</p> + +<pre class="brush: html notranslate">{% extends "base_generic.html" %} +{% block content %} +<p>We've emailed you instructions for setting your password. If they haven't arrived in a few minutes, check your spam folder.</p> +{% endblock %} +</pre> + +<h4 id="Correo_electrónico_de_reinicio_de_contraseña">Correo electrónico de reinicio de contraseña</h4> + +<p>Esta plantilla suministra el texto HTML del correo electrónico, y contiene el enlace de reseteo que enviaremos a los usuarios. Crea <strong>/locallibrary/templates/registration/password_reset_email.html</strong>, y establece el siguiente contenido:</p> + +<pre class="brush: html notranslate">Someone asked for password reset for email \{{ email }}. Follow the link below: +\{{ protocol}}://\{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %} +</pre> + +<h4 id="Confirmación_de_reinicio_de_contraseña">Confirmación de reinicio de contraseña</h4> + +<p>Esta página es donde introduces una nueva contraseña después de pinchar el enlace en el correo electrónico de reinicio de contraseña. Crea <strong>/locallibrary/templates/registration/password_reset_confirm.html</strong>, y establece el siguiente contenido:</p> + +<pre class="brush: html notranslate">{% extends "base_generic.html" %} + +{% block content %} + + {% if validlink %} + <p>Please enter (and confirm) your new password.</p> + <form action="" method="post"> + <div style="display:none"> + <input type="hidden" value="\{{ csrf_token }}" name="csrfmiddlewaretoken"> + </div> + <table> + <tr> + <td>\{{ form.new_password1.errors }} + <label for="id_new_password1">New password:</label></td> + <td>\{{ form.new_password1 }}</td> + </tr> + <tr> + <td>\{{ form.new_password2.errors }} + <label for="id_new_password2">Confirm password:</label></td> + <td>\{{ form.new_password2 }}</td> + </tr> + <tr> + <td></td> + <td><input type="submit" value="Change my password" /></td> + </tr> + </table> + </form> + {% else %} + <h1>Password reset failed</h1> + <p>The password reset link was invalid, possibly because it has already been used. Please request a new password reset.</p> + {% endif %} + +{% endblock %} +</pre> + +<h4 id="Reinicio_de_contraseña_completado">Reinicio de contraseña completado</h4> + +<p>Este es el último paso de la plantilla de reinicio de contraseña, que es mostrada para notificarte cuando el reinicio de contraseña ha tenido éxito. Crea <strong>/locallibrary/templates/registration/password_reset_complete.html</strong>, y establece el siguiente contenido:</p> + +<pre class="brush: html notranslate">{% extends "base_generic.html" %} +{% block content %} + +<h1>The password has been changed!</h1> +<p><a href="{% url 'login' %}">log in again?</a></p> + +{% endblock %}</pre> + +<h3 id="Probando_las_nuevas_páginas_de_autenticación">Probando las nuevas páginas de autenticación</h3> + +<p>Ahora que has añadido la configuración URL y creado todas estas plantillas, ¡las páginas de autenticación ahora deberían funcionar!</p> + +<p>Puedes probar las nuevas páginas de autenticación intentando iniciar sesión y entonces cerrar sesión con tu cuenta de super administrador usando estas URLs:</p> + +<ul> + <li><a href="http://127.0.0.1:8000/accounts/login/">http://127.0.0.1:8000/accounts/login/</a></li> + <li><a href="http://127.0.0.1:8000/accounts/logout/">http://127.0.0.1:8000/accounts/logout/</a></li> +</ul> + +<p>Serás capaz de probar la funcionalidad de reinicio de contraseña desde el enlace de la página de inicio de sesión. <strong>¡Ten cuidado con el hecho de que Django solamente enviará correos de reinicio a las direcciones (usuarios) que ya están almacenadas en la base de datos!</strong></p> + +<div class="note"> +<p><strong>Nota</strong>: El sistema de reinicio de contraseña requiere que tu sitio web soporte envío de correo, que está más allá del ámbito de este artículo, por lo que esta parte <strong>no funcionará todavía</strong>. Para permitir el testeo, establece la siguiente línea al final de tu fichero settings.py. Esto registra en la consola cualquier envío de correo electrónico (y así puedes copiar el enlace de reinicio de contraseña desde dicha consola).</p> + +<pre class="brush: python notranslate">EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' +</pre> + +<p>Para más información, ver <a href="https://docs.djangoproject.com/en/1.10/topics/email/">Sending email</a> (Django docs).</p> +</div> + +<h2 id="Probando_contra_usuarios_autenticados">Probando contra usuarios autenticados</h2> + +<p>Esta sección mira a lo que podemos hacer para controlar selectivamente el contenido que el usuario ve basado en si ha iniciado sesión o no.</p> + +<h3 id="Probando_en_plantillas">Probando en plantillas</h3> + +<p>Puedes obtener información en las plantillas sobre el usuario que actualmente ha iniciado sesión con la variable de plantillas <code>\{{ user }}</code> (esto se añade por defecto al contexto de la plantilla cuando configuras el proyecto como hicimos en nuestro esqueleto).</p> + +<p>Es típico que primero pruebes con la variable de plantilla <code>\{{ user.is_authenticated }}</code> para determinar si el usuario puede ver el contenido específico. Para demostrar esto, lo siguiente que haremos será actualizar nuestra barra lateral "sidebar" para mostrar un enlace de inicio de sesión "Login" si el usuario no ha iniciado sesión, y un cierre de sesión "Logout" en el caso de que sí la haya iniciado.</p> + +<p>Abre la plantilla base (<strong>/locallibrary/catalog/templates/base_generic.html</strong>) y copia el siguiente texto en el bloque <code>sidebar</code>, justamente antes de la etiqueta de plantilla <code>endblock</code> .</p> + +<pre class="brush: html notranslate"> <ul class="sidebar-nav"> + + ... + + <strong>{% if user.is_authenticated %}</strong> + <li>User: <strong>\{{ user.get_username }}</strong></li> + <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li> + <strong>{% else %}</strong> + <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li> + <strong>{% endif %} </strong> + </ul></pre> + +<p>Como puedes ver, usamos las etiquetas de plantilla <code>if</code>-<code>else</code>-<code>endif</code> para condicionar el texto mostrado basado en si <code>\{{ user.is_authenticated }}</code> es cierto o no. Si el usuario está autenticado, sabemos que tenemos un usuario válido, por lo que llamamos a <strong>\{{ user.get_username }} </strong>para mostrar su nombre.</p> + +<p>Creamos los enlaces URLs del inicio y del cierre de sesión usando la etiqueta de plantilla <code>url</code> y los nombres de las respectivas configuraciones de las URL. Nótese también cómo hemos añadido <code>?next=\{{request.path}}</code> al final de las URLs. Lo que esto hace es añadir el párametro URL <font face="Consolas, Liberation Mono, Courier, monospace">next</font> que contiene la dirección (URL) de la página <em>actual</em>, al final de la URL enlazada. Después de que el usuario haya iniciado o cerrado sesión con éxito, las vistas usarán el valor de este "<code>next</code>" para redirigir al usuario de vuelta a la página donde pincharon primeramente el enlace de inicio/cierre de sesión.</p> + +<div class="note"> +<p><strong>Nota</strong>: ¡Pruébalo! Si estás en la página de inicio y pinchas en la barra lateral "sidebar", después de que la operación se complete deberías acabar de vuelta en la misma página.</p> +</div> + +<h3 id="Probando_en_vistas">Probando en vistas</h3> + +<p>Si estás usando vistas basadas en funciones, la forma más facil para restringir el acceso a tus funciones es aplicar el decorador <code>login_required</code> a tu función de vista, como se muestra más abajo. Si el usuario ha iniciado sesión entonces tu código de vista se ejecutará como normalmente lo hace. Si el usuario no ha iniciado sesión, se redirigirá a la URL de inicio de sesión definida en tu configuración de proyecto (<code>settings.LOGIN_URL</code>), pasando el directorio absoluto actual como el parámetro URL <code>next</code>. Si el usuario tiene éxito en el inicio de sesión entonces será devuelto a esta página, pero esta vez autenticado.</p> + +<pre class="brush: python notranslate">from django.contrib.auth.decorators import login_required + +@login_required +def my_view(request): + ...</pre> + +<div class="note"> +<p><strong>Nota:</strong> ¡Tú puedes hacer el mismo tipo de cosas manualmente probando con <code>request.user.is_authenticated</code>, pero el decorador es mucho más conveniente!</p> +</div> + +<p>De manera similar, la forma más fácil de restringir el acceso a los usuarios que han iniciado sesión en tus vistas basadas en clases es extender de <code>LoginRequiredMixin</code>. Necesitas declarar primeramente este <code>mixin </code>en la lista de super clases, antes de la clase de vista principal.</p> + +<pre class="brush: python notranslate">from django.contrib.auth.mixins import LoginRequiredMixin + +class MyView(LoginRequiredMixin, View): + ...</pre> + +<p>Esto tiene exactamente el mismo comportamiento de redirección que el decorador <code>login_required</code>. También puedes especificar una localización alternativa para redirigir al usuario si no están autenticados (<code>login_url</code>), y un nombre de parámetro URL en lugar de "<code>next</code>" para insertar el directorio absoluto actual (<code>redirect_field_name</code>).</p> + +<pre class="brush: python notranslate">class MyView(LoginRequiredMixin, View): + login_url = '/login/' + redirect_field_name = 'redirect_to' +</pre> + +<p>Para detalles adicionales, echa un vistazo a <a href="https://docs.djangoproject.com/en/1.10/topics/auth/default/#limiting-access-to-logged-in-users">Django docs</a>.</p> + +<h2 id="Ejemplo_-_listando_los_libros_del_usuario_actual">Ejemplo - listando los libros del usuario actual</h2> + +<p>Ahora que sabemos cómo restringir una página a un usuario concreto, vamos a crear una vista de los libros que el usuario tiene prestados actualmente.</p> + +<p>Desafortunadamente, ¡todavía no tenemos una forma de pedir prestados los libros a los usuarios! Por eso, antes de que podamos crear la lista de libros vamos primeramente a extender el modelo <code>BookInstance</code> para dar soporte al concepto de pedir prestado y usar la aplicación del Administrador Djando para alquilar un número de libros a nuestro usuario de prueba.</p> + +<h3 id="Modelos">Modelos</h3> + +<p>Primero vamos a hacer posible para los usuarios tener una <code>BookInstance</code> en alquiler (ya tenemos un <code>status</code> y una fecha <code>due_back</code>, pero no tenemos todavía una asociación entre este modelo y un Usuario). Crearemos uno usando un campo <code>ForeignKey</code> (uno-a-muchos). También necesitaremos un mecanismo sencillo para probar si un libro alquilado está atrasado.</p> + +<p>Abre <strong>catalog/models.py</strong>, e importa el modelo <code>User</code> de <code>django.contrib.auth.models</code> (añade esto justamente debajo de la anterior línea de importación, arriba del todo del fichero, para que el <code>User</code> esté disponible para el posterior código del que hace uso):</p> + +<pre class="brush: python notranslate">from django.contrib.auth.models import User +</pre> + +<p>Después añade el campo <code>borrower</code> al modelo <code>BookInstance</code>:</p> + +<pre class="brush: python notranslate">borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) +</pre> + +<p>Ya que estamos aquí, vamos a añadir una propiedad que podamos llamar desde nuestras plantillas para decir si una instancia particular de un libro está atrasada. Mientras que podríamos calcular esto en la misma plantilla, usar una propiedad (<a href="https://docs.python.org/3/library/functions.html#property">property</a>) como se muestra abajo será mucho más eficiente.</p> + +<pre class="brush: python notranslate">from datetime import date + +@property +def is_overdue(self): + if self.due_back and date.today() > self.due_back: + return True + return False</pre> + +<div class="note"> +<p><strong>Nota</strong>: Primeramente verificamos si la fecha <code>due_back</code> está vacía antes de realizar una comparación. Un campo vacío <code>due_back</code> provocaría a Django arrojar un error en lugar de mostrar la página: los valores vacíos no son comparables. ¡Esto no es algo que queramos para la experiencia de nuestros usuarios!</p> +</div> + +<p>Ahora que hemos actualizado nuestros modelos, necesitaremos hacer migraciones actuales en el proyecto y entonces aplicar esas migraciones:</p> + +<pre class="brush: bash notranslate">python3 manage.py makemigrations +python3 manage.py migrate +</pre> + +<h3 id="Administrador">Administrador</h3> + +<p>Ahora abre <strong>catalog/admin.py</strong>, y añade el campo <code>borrower</code> a la clase <code>BookInstanceAdmin</code> en ambas <code>list_display</code> y <code>fieldsets</code> como se muestra abajo. Esto hará el campo visible en la sección de Administrador, por lo que podemos asignar un <code>User</code> a una <code>BookInstance</code> cuando lo necesitemos.</p> + +<pre class="brush: python notranslate">@admin.register(BookInstance) +class BookInstanceAdmin(admin.ModelAdmin): + list_display = ('book', 'status'<strong>, 'borrower'</strong>, 'due_back', 'id') + list_filter = ('status', 'due_back') + + fieldsets = ( + (None, { + 'fields': ('book','imprint', 'id') + }), + ('Availability', { + 'fields': ('status', 'due_back'<strong>,'borrower'</strong>) + }), + )</pre> + +<h3 id="Alquilar_unos_pocos_libros">Alquilar unos pocos libros</h3> + +<p>Ahora que es posible alquilar libros a un usuario específico, ve y alquila un número de registros <code>BookInstance</code>. Establece su campo <code>borrowed</code> a tu usuario de prueba, establece el <code>status</code> "On loan" (en alquiler) y establece fechas de vencimiento tanto en el futuro como en el pasado.</p> + +<div class="note"> +<p><strong>Nota</strong>: No escribiremos el proceso, porque ¡ya sabes cómo usar el sitio de Administrador!</p> +</div> + +<h3 id="Vista_en_alquiler">Vista en alquiler</h3> + +<p>Ahora añadiremos una vista para obtener la lista de todos los libros que han sido alquilados al usuario actual. Usaremos la misma vista de lista genérica basada en clases con la que estamos familiarizada, pero esta vez también importaremos y extenderemos de <code>LoginRequiredMixin</code>, por lo que solamente un usuario que ha iniciado sesión podrá llamar a esta vista. También elegiremos declarar una <code>template_name</code> en lugar de usar la de por defecto, porque quizás acabemos teniendo unas pocas listas diferentes de registros de BookInstance, con diferentes vistas y plantillas.</p> + +<p>Añade lo siguiente a catalog/views.py:</p> + +<pre class="brush: python notranslate">from django.contrib.auth.mixins import LoginRequiredMixin + +class LoanedBooksByUserListView(LoginRequiredMixin,generic.ListView): + """ + Generic class-based view listing books on loan to current user. + """ + model = BookInstance + template_name ='catalog/bookinstance_list_borrowed_user.html' + paginate_by = 10 + + def get_queryset(self): + return BookInstance.objects.filter(borrower=self.request.user).filter(status__exact='o').order_by('due_back')</pre> + +<p>Para restringir nuestra consulta a solamente los objetos BookInstance del usuario actual, vamos a reimplementar <code>get_queryset()</code> como se muestra abajo. Nótese que "o" es el código almacenado para "on loan" (en alquiler) y vamos a ordenar por la fecha <code>due_back</code> para que los elementos más antiguos se muestren primero.</p> + +<h3 id="Configuración_URL_para_libros_alquilados">Configuración URL para libros alquilados</h3> + +<p>Ahora abre <strong>/catalog/urls.py</strong> y añade la url <code>url()</code> apuntando a la vista anterior (puedes simplemente copiar el texto de abajo al final del fichero).</p> + +<pre class="brush: python notranslate">urlpatterns += [ + url(r'^mybooks/$', views.LoanedBooksByUserListView.as_view(), name='my-borrowed'), +]</pre> + +<h3 id="Plantilla_para_libros_alquilados">Plantilla para libros alquilados</h3> + +<p>Ahora todo lo que necesitamos hacer para esta página es añadir una plantilla. Primero, creamos el fichero plantilla <strong>/catalog/templates/catalog/bookinstance_list_borrowed_user.html</strong> y establecemos el siguiente contenido en ella:</p> + +<pre class="brush: python notranslate">{% extends "base_generic.html" %} + +{% block content %} + <h1>Borrowed books</h1> + + {% if bookinstance_list %} + <ul> + + {% for bookinst in bookinstance_list %} + <li class="{% if bookinst.is_overdue %}text-danger{% endif %}"> + <a href="{% url 'book-detail' bookinst.book.pk %}">\{{bookinst.book.title}}</a> (\{{ bookinst.due_back }}) + </li> + {% endfor %} + </ul> + + {% else %} + <p>There are no books borrowed.</p> + {% endif %} +{% endblock %}</pre> + +<p>Esta plantilla es muy similar a esas que hemos creado previamente para los objetos <code>Book</code> y <code>Author</code>. La única "cosa" nueva aquí es que comprobamos el método que hemos añadido en el modelo <code>(bookinst.is_overdue</code>) y lo usamos para cambiar el color de los elementos atrasados.</p> + +<p>Cuando el servidor de desarrollo esté en ejecución, deberías ser capaz de ver la lista de los usuarios que han iniciado sesión en tu navegador en <a href="http://127.0.0.1:8000/catalog/mybooks/">http://127.0.0.1:8000/catalog/mybooks/</a>. Prueba esto con tu usuario iniciado en la sesión y cerrado en la sesión (en el segundo caso, deberías ser redirigido a la página de inicio).</p> + +<h3 id="Añadir_la_lista_a_la_barra_lateral">Añadir la lista a la barra lateral</h3> + +<p>El último paso es añadir un enlace para esta nueva página en la barra lateral "sidebar". Pondremos esto en la misma sección donde mostramos otra información para el usuario que ha iniciado la sesión.</p> + +<p>Abre la plantilla base (<strong>/locallibrary/catalog/templates/base_generic.html</strong>) y añade la línea en negrita a la barra lateral como se muestra.</p> + +<pre class="brush: python notranslate"> <ul class="sidebar-nav"> + {% if user.is_authenticated %} + <li>User: \{{ user.get_username }}</li> +<strong> <li><a href="{% url 'my-borrowed' %}">My Borrowed</a></li></strong> + <li><a href="{% url 'logout'%}?next=\{{request.path}}">Logout</a></li> + {% else %} + <li><a href="{% url 'login'%}?next=\{{request.path}}">Login</a></li> + {% endif %} + </ul> +</pre> + +<h3 id="¿Cómo_se_ve">¿Cómo se ve?</h3> + +<p>Cuando cualquier usuario ha iniciado sesión, verán el enlace <em>My Borrowed</em> (Mis Alquileres) en la barra lateral, y la lista de libros mostrados como se ve abajo (¡el primer libro no tiene fecha de vencimiento, que es un bug que esperamos arreglar en un tutorial posterior!).</p> + +<p><img alt="Library - borrowed books by user" src="https://mdn.mozillademos.org/files/14105/library_borrowed_by_user.png" style="border-style: solid; border-width: 1px; display: block; height: 215px; margin: 0px auto; width: 530px;"></p> + +<h2 id="Permisos">Permisos</h2> + +<p>Los permisos están asociados con los modelos, y definen las operaciones que pueden llevarse a cabo en un modelo instanciado por un usuario que tiene el permiso. Por defecto, Django automáticamente da los permisos <em>add</em>, <em>change</em>, and <em>delete</em> (añadir, cambiar y eliminar) a todos los modelos, que permiten a los usuarios con los permisos realizar las acciones asociadas a través del sitio de Administrador. Tú puedes definir tus propios permisos a los modelos y concedérselos a usuarios específicos. También puedes cambiar los permisos asociados con diferentes instancias del mismo modelo.</p> + +<p>Probar permisos en vistas y plantillas es muy similar a probar sobre el estado de autenticación (y, de hecho, probar un permiso también prueba una autenticación).</p> + +<h3 id="Modelos_2">Modelos</h3> + +<p>La definición de permisos está hecha en la sección del modelo "<code>class Meta</code>", usando el campo <code>permissions</code>. Puedes especificar tantos permisos como necesites en una tupla, cada permiso está definido a sí mismo en una tupla anidada que contiene el nombre del permiso y el valor mostrado del mismo. Por ejemplo, podríamos definir un permiso para permitir a un usuario marcar un libro que ya ha sido devuelto, como se muestra:</p> + +<pre class="brush: python notranslate">class BookInstance(models.Model): + ... + class Meta: + ... +<strong> permissions = (("can_mark_returned", "Set book as returned"),) </strong> </pre> + +<p>Podríamos asignar el permiso a un grupo bibliotecario "Librarian" en el sitio de Administración.</p> + +<p>Abre <strong>catalog/models.py</strong>, y añade el permiso como se muestra arriba. Necesitarás volver a ejecutar tus migraciones (ejecutar <code>python3 manage.py makemigrations</code> y <code>python3 manage.py migrate</code>) para actualizar la base de datos de forma apropiada.</p> + +<h3 id="Plantillas">Plantillas</h3> + +<p>Los permisos del usuario actual están almacenados en una variable de plantilla llamada <code>\{{ perms }}</code>. Puedes comprobar si el usuario actual tiene un permiso particular usando el nombre de variable específico con la "app" asociada en Django — ej. <code>\{{ perms.catalog.can_mark_returned }}</code> será <code>True</code> (cierto) si el usuario tiene el permiso, y <code>False</code> (falso) en otro caso. De forma típica probamos el permiso usando la etiqueta de plantilla <code>{% if %}</code> como se muestra:</p> + +<pre class="brush: python notranslate">{% if perms.catalog.<code>can_mark_returned</code> %} + <!-- We can mark a BookInstance as returned. --> + <!-- Perhaps add code to link to a "book return" view here. --> +{% endif %} +</pre> + +<h3 id="Vistas">Vistas</h3> + +<p>Los permisos pueden ser probados en una vista de función usando el decorador <code>permission_required</code> o en una vista basada en clases usando el <code>PermissionRequiredMixin</code>. El patrón y el comportamiento son los mismos que para la autenticación de inicio de sesión, aunque desde luego podrías razonablemente tener que añadir múltiples permisos.</p> + +<p>Decorador de vista de funciones:</p> + +<pre class="brush: python notranslate">from django.contrib.auth.decorators import permission_required + +@permission_required('catalog.<code>can_mark_returned</code>') +@permission_required('catalog.<code>can_edit</code>') +def my_view(request): + ...</pre> + +<p>"Mixin" de permisos requeridos para vistas basadas en clases:</p> + +<pre class="brush: python notranslate">from django.contrib.auth.mixins import PermissionRequiredMixin + +class MyView(PermissionRequiredMixin, View): + permission_required = 'catalog.<code>can_mark_returned</code>' + # Or multiple permissions + permission_required = ('catalog.<code>can_mark_returned</code>', 'catalog.can_edit') + # Note that 'catalog.can_edit' is just an example + # the catalog application doesn't have such permission!</pre> + +<h3 id="Ejemplo">Ejemplo</h3> + +<p>Nosotros no actualizaremos la <em>LocalLibrary</em> aquí; ¡quizás en el siguiente tutorial!</p> + +<h2 id="Desafíate_a_ti_mismo">Desafíate a ti mismo</h2> + +<p>Anteriormente en este artículo te mostramos cómo crear una página para el usuario actual para listar los libros que había pedido prestado. El desafío ahora es crear una página similar que solamente sea visible para los bibliotecarios, que muestre todos los libros que hayan sido prestados, y que incluya el nombre de cada prestatario.</p> + +<p>Deberías ser capaz de seguir el mismo patrón que el de la otra vista. La principal diferencia es que necesitarás restringir la vista a solamente los bibliotecarios. Podrías hacer esto basándote en si es un miembro de los empleados (decorador de función: <code>staff_member_required</code>, variable de plantilla: <code>user.is_staff</code>) pero nosotros te recomendamos que en su lugar uses el permiso <code>can_mark_returned</code> y <code>PermissionRequiredMixin</code>, como se describe en la sección anterior.</p> + +<div class="warning"> +<p><strong>Importante</strong>: Recuerda no usar tu súper usuario para pruebas basadas en permisos (la comprobación de permisos siempre devuelve cierto para súper usuarios, ¡incluso si un permiso no ha sido definido todavía!). En su lugar, crea un usuario bibliotecario, y añade entonces la capacidad requerida.</p> +</div> + +<p>Cuando hayas terminado, tu página debería verse algo parecida a la captura de pantalla de abajo.</p> + +<p><img alt="All borrowed books, restricted to librarian" src="https://mdn.mozillademos.org/files/14115/library_borrowed_all.png" style="border-style: solid; border-width: 1px; display: block; height: 283px; margin: 0px auto; width: 500px;"></p> + +<ul> +</ul> + +<h2 id="Sumario">Sumario</h2> + +<p>Excelente trabajo — has creado un sitio web para que los miembros de la biblioteca puedan iniciar sesión y ver su propio contenido, y los bibliotecarios (con el permiso correcto) puedan usarlo para ver todos los libros alquilados y sus prestatarios. En este momento estamos todavía simplemente viendo contenido, pero los mismos principios y técnicas son usados cuando empiezas a modificar y añadir datos.</p> + +<p>En nuestro siguiente artículo observaremos cómo puedes usar los formularios de Django para recoger la entrada de datos del usuario, y entonces empezar a modificar algunos de nuestros datos almacenados.</p> + +<h2 id="Ver_también">Ver también</h2> + +<ul> + <li><a href="https://docs.djangoproject.com/en/1.10/topics/auth/">Autenticación de Usuario en Django</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/1.10/topics/auth/default//">Usando el sistema por defecto de Autenticación de Django</a> (Django docs)</li> + <li><a href="https://docs.djangoproject.com/en/1.10/topics/class-based-views/intro/#decorating-class-based-views">Introducción a clases basadas en vistas > Decoradores</a> (Django docs)</li> +</ul> + +<p>{{PreviousMenuNext("Learn/Server-side/Django/Sessions", "Learn/Server-side/Django/Forms", "Learn/Server-side/Django")}}</p> + +<h2 id="En_este_módulo">En este módulo</h2> + +<ul> + <li><a href="/es/docs/Learn/Server-side/Django/Introducción">Introducción a Django</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/development_environment">Configurando un entorno de desarrollo Django</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Tutorial_local_library_website">Tutorial de Django: El sito web de la Biblioteca Local</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/skeleton_website">Tutorial de Django Parte 2: Creando el esqueleto de un sitio web</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Models">Tutorial de Django Parte 3: Usando modelos</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Admin_site">Tutorial de Django Parte 4: Sitio de administración de Django</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Home_page">Tutorial de Django Parte 5: Creando nuestra página de inicio</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Generic_views">Tutorial de Django Parte 6: Listas genéricas y vistas de detalle</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Sessions">Tutorial de Django Parte 7: Framework de sesiones</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Authentication">Tutorial de Django Parte 8: Autenticación de usuarios y permisos</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Forms">Tutorial de Django Parte 9: Trabajando con formularios</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Testing">Tutorial de Django Parte 10: Probando una aplicación web de Django</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/Deployment">Tutorial de Django Parte 11: Poniendo Django en producción</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/web_application_security">Seguridad en aplicaciones web Django</a></li> + <li><a href="/es/docs/Learn/Server-side/Django/django_assessment_blog">DIY Django mini blog</a></li> +</ul> + +<div id="gtx-trans" style="position: absolute; left: 170px; top: 8184.58px;"> +<div class="gtx-trans-icon"></div> +</div> |