Curso Django: Gestión de usuarios
La gestión de usuarios es un proceso bastante común en todo proyecto, muchos desarrolladores han programado funcionalidades de autenticación una y otra vez a lo largo de muchos años y siempre funciona de la misma manera. Django quiere simplificarnos la vida y es por ello que viene ya con un sistema de autenticación completo que gestiona cuentas de usuario, grupos, permisos, sesiones de usuario y cookies.
El sistema de autenticación de Django, tiene una documentación muy completa incluyendo algunos ejemplos de uso. Abarcarlos todos puede complicar la didactica del curso, así que voy a implementar solamente estas funcionalidades que son más frecuentes:
- Creación de usuarios
- Autenticación de usuarios
- Acceso restringido
- Cierre de sesión
El sistema de autenticación necesita de django.contrib.auth. por lo tanto, es necesario agregar estas líneas a nuestro views.py:
from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.forms import AuthenticationForm from django.contrib.auth import login, authenticate, logout from django.contrib.auth.decorators import login_required
Si deseas puedes unir en una sola instrucción a UsertCreationForm y AuthenticationForm, solamente separados por comas, algo así: from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
Creación de usuarios
Para crear usuarios (sin la interfaz administrativa de Django), podemos usar el formulario que viene con Django, su nombre es UserCreationForm from django.contrib.auth.forms import UserCreationForm, AuthenticationForm que pertenece a django.contrib.auth.forms.
Creamos la siguiente vista (nuevo_usuario):
Luego la siguiente plantilla (nuevousuario.html):
Y agregamos la siguiente línea a urls.py:
url(r'^usuario/nuevo$','principal.views.nuevo_usuario'),
Si accedemos a la URL: http://127.0.0.1:8000/usuario/nuevo veremos lo siguiente:
Podemos probar que crea un usuario nuevo, también puedes agregar un enlace a tus plantillas anteriores, para mejorar la navegación.
Autenticación de usuarios
Ahora vamos a crear la interfaz para el ingreso al sistema, para ello usaremos el formulario AuthenticationForm, que también pertenece a django.contrib.auth.forms y usaremos authenticate y login de django.contrib.auth.
Agregamos la siguiente vista(ingresar) :
Notar que existe una condicional que menciona “is_active”, eso nos indica que el usuario puede que exista en el sistema, pero también debe estar activo para poder ingresar.
Crearemos las plantillas (noactivo.html, nousuario.html e ingresar.html):
Agregamos la siguiente línea al urls.py:
url(r'^ingresar/$','principal.views.ingresar'),
Al probarlo ingresamos a la dirección http://127.0.0.1:8000/ingresar/ , si tenemos un usuario inactivo (se puede activar o desactivar a un usuario desde la interfaz administrativa de Django), nos saldrá el contenido de la plantilla noactivo.html, si nos equivocamos de credenciales saldra nousuario.html y si le damos los datos adecuados, nos saldra el error 404, porque aún no hemos creado la vista para( /privado).
Acceso restringido
Para complementar nuestro ejemplo anterior (/privado) vamos a crear una vista que permita manejar esto, esta vista tendra la restricción de autenticación, quiere decir que se necesita ingresar al sistema para poder ver su contenido, para esto vamos a usar login_required que pertenece a django.contrib.auth.decorators, se usa mediante la sintaxis:
@login_required(login_url='/ingresar')
Esta línea se debe agregar antes de cada vista, para poder activar esta restricción, nuestra vista para privado quedaría de esta manera:
Notar que ahora usaremos los datos del modelo User de Django, la documentación de estos campos de usuario es de mucha ayuda.
Podríamos modificar nuestra vista ingresar para que no vuelva aparecer el formulario de registro, mientras el usuario ya se encuentra dentro del sistema, quedaría de la siguiente manera:
Fijarse que estás líneas fueron agregadas:
if not request.user.is_anonymous(): return HttpResponseRedirect('/privado')
Agregaríamos al urls.py:
url(r'^privado/$','principal.views.privado'),
Y crearíamos la plantilla (privado.html):
Nuestro resultado sería:
Esto nos obligará a tener una manera de cerrar la sesión.
Cierre de sesión
Para el cierre de sesión necesitamos logout que se encuentra en django.contrib.auth, la vista sería tan simple como esto:
Y en urls.py está línea:
url(r'^cerrar/$', 'principal.views.cerrar'),
Solo basta con ingresar a http://127.0.0.1:8000/cerrar/ y se cerrara la sesión.
El archivo urls.py quedaría, al final de todas las modificaciones, de la siguiente manera:
Repositorio del proyecto e Indicaciones finales
Si desean revisar el código completo del proyecto pueden hacerlo desde el repositorio en github, para comparar y resolver cualquier duda, eviten solo copiar y pegar, mejor escriban el código será más educativo.
Ya estamos a un capítulo para terminar nuestro curso básico de Django, quiero recordarles que este curso en Maestros del Web, tiene como objetivo, incentivar el uso de Python y Django a aquellos que conocen poco o nada de ellos. Lamento no poder abarcar temas más avanzados, como algunos piden por los comentarios, espero que comprendan que no lo hago porque corro el riesgo de que se vuelva complicado y no logre el objetivo.
La próxima semana terminamos el curso con el despliegue en el servidor y las opciones que tenemos para publicar nuestro proyecto, como todas las semanas sus comentarios y tweets enriquecen este curso, sigan haciéndolo.
Que tengan un buen inicio de semana
Gracias Sergio, es el mejor material en castellano que conozco sobre django. Una pregunta, ¿como funciona el tema de los grupos?. pues necesito hacer un sitio que restringa el acceso a ciertas partes según el usuario y las verdad es que no tengo idea. Desde ya muchisimas gracias
Gracias Martín por seguir el curso .
El tema de los grupos esta detallado en esta parte de la documentación (https://docs.djangoproject.com/en/dev/topics/auth/#groups), incluyendo las restricciones o permisos (https://docs.djangoproject.com/en/dev/topics/auth/#permissions). También puedes ver un ejemplos aquí (http://djangosnippets.org/snippets/1054/)
Hmmm genial todo esta super !! :3
…Sergio te felicito, muy buen texto, bien claro, preciso…excelente!!!…muchas gracias
Primero Agradecerte por el excelente curso q llevas a cabo, darte mis felicitaciones es una joya realmente.
Segundo me surgio un problema con el capitulo anterior de los STATIC FILES, todo funciona de maravilla cuando lo pruebo en el servidor que trae python, pero al probarlo en el servidor apache me da el siguiente error al querer ver los archivos .css o .js:
Page not found (404)
Request Method: GET
Request URL: http://localhost/rain/static/js/demos.js
Using the URLconf defined in recetario.urls, Django tried these URL patterns, in this order:
^$
^usuarios/$
^recetas/$
^receta/(?P\d+)$
^receta/nueva/$
^comenta/$
^sobre/$
^contacto/$
^admin/doc/
^admin/
^media/(?P.*)$
The current URL, static/js/demos.js, didn’t match any of these.
ademas de no aplicarse ninguno de los estilos de base.css, no se si hay alguna configuracion que hacer en el servidor de apache para q solucione este problema. Agradecerte y felicitarte una vez mas.
Hola Sergio, muchas gracias por tu colaboración con la comunidad de Python y Django. Una pregunta, será posible una segunda parte de este curso? algo mas avanzado?
Gracias Jesus, por seguir el curso. Para usar Django con un servidor como Apache hay configuraciones que hacer, y es justamente el tema de la próxima semana. Un poquito de paciencia
Hola Ricky, pues algo estaremos tramando, si nos sigues por Twitter ahi te enteraras de primera mano
Muchas gracias Sergio por atender mi pregunta esperare con muchas ansias el tema de la siguiete semana =D
Aprender con Sergio, nunca fue más facil y rápido…!
Al momento de implementar la autenticacion del usuario en el sistema y probarlo en el navegador no obtengo resultados al momento de completar el formulario solo se carga la página de nuevo, ¿a alguien más le pasa o le ha pasado eso?
Gracias Sergio, clara como agua cristalina, gracias por tu tiempo, y si sigues con un segundo curso mas avanzado. Aqui tienes a un servidor que lo estara siguiento, como en este primero.
¿Eso quiere decir que la siguiente clase será la última?
Si Sergio,, vamos,,, te seguiremos en un tuto más avanzado …. gracias por estos temas
Hola Alvaro, si pusieras el codigo de tu vista ayudaras mucho a ayudarte, pero creo que lo que sucede es que en tu vista tienes en la parte de la validacion del AuthenticationForm lo siguiente:
if formulario.is_valid():
esto deberias cambiarlo por:
if formulario.is_valid:
sin los parentesis.
😀
Puede ser tambien que estes redireccionando a ” / ” cuando se hace el login en ves de redireccionar a ” /privado “
No creo que sea eso ya que el dice que se vuelve a cargar la misma pagina del formulario, eso significa que no valida el formulario y no crea la sesion del usuario
Mil gracias sergio por responder, (como decimos en mi país) ¡Me sacaste las papas del orno!!! jajaja
Por favor sigue así, el curso esta excelente.
Sergio primero darte las gracias, me han ayudado mucho tus tutoriales, tengo una consulta en caso yo quisiera elaborar un formulario para actualizar el password, django tendra uno ya echo o tengo que hacerlo.
gracias
Ya viene uno hecho :3
Excelente el curso Sergio, la vedad que muy practico y bien explicado, y como dicen los demas si hay una segunda parde de cosas mas avanzadas se te agradeceria de todo corazon !
Hola Jose Carlos, gracias por seguir el curso. Mira este enlace https://docs.djangoproject.com/en/dev/topics/auth/#module-django.contrib.auth.forms ahi notaras un PasswordChangeForm
Quizas haya, esta en planes, pero despues de que esta guía este en versión descargable y disponible en Amazon para el Kindle
He hecho el curso en 2 días y estoy ansioso por aprender mucho mas.
Sergio, gracias por este excelente curso, deja un muy buen sabor de boca para seguir aprendiendo django.
De nuevo muchas gracias y saludos!
Gracias Cristhian por seguir el curso, aún falta el último capítulo (mañana).
Esperamos Sergio I. M. =)
Sergio gracias por responder ya pude realizar el formulario de cambio de password, tengo otra duda mira yo tengo un formulario de creacion de usuarios personalizados el cual quiero utilizar en lugar de UserCreationForm sobre que modelo tengo que trabajar para guardar los datos de mi nuevo formulario tendras algun ejmplo, muchas gracias de antemanoo =)
Buenas he estado aprendiendo django gracias a este curso tengo una duda que no he podido resolver, si yo creo un usuario desde la interfaz de administracion y le doy un permiso de modificar este usuario puede usar la interfaz de administracion para modificar en el modulo que le di permiso?? he estado tratando de averiguar como iniciar sesion como usuario y usar la interfaz de administracion pero como usuario no como administrador es esto posible??
Estimado.
Una consulta, desde donde carga el archivo ‘base.html’ ? al tratar de cargar el ejemplo me arroja el error que no existe este documento.
Gracias.
Hola que tal Sergio, primeramente te felicito por este magnifico tutorial de Django que haz compartido con todos nosotros, y solo para decirte que me surgió una duda, ¿como puedo controlar cuando dura la sesión del usuario?, de antemano muchas gracias y éxito
Hola Sergio, de nuevo quiero agradecerte por el curso. Mira tengo un problema cuando quiero mostrar el ingreso, me sale este error y no encuentro donde es que me falta el HttpResponse.
The view principal.views.ingresar didn’t return an HttpResponse object.
Request Method: GET
Request URL: http://127.0.0.1:8000/ingresar/
Django Version: 1.4.1
Exception Type: ValueError
Exception Value:
The view principal.views.ingresar didn’t return an HttpResponse object.
Exception Location: C:\Python27\lib\site-packages\django\core\handlers\base.py in get_response, line 129
Python Executable: C:\Python27\python.exe
Python Version: 2.7.3
Python Path:
[‘C:\\Python27\\Scripts\\recetario’,
‘C:\\Windows\\system32\\python27.zip’,
‘C:\\Python27\\DLLs’,
‘C:\\Python27\\lib’,
‘C:\\Python27\\lib\\plat-win’,
‘C:\\Python27\\lib\\lib-tk’,
‘C:\\Python27’,
‘C:\\Python27\\lib\\site-packages’,
‘C:\\Python27\\lib\\site-packages\\PIL’]
Server time: vie, 7 Sep 2012 01:10:21 -0500
Perdon por esto, ya estaba en el capitulo.
Hola Sergio, te agradezco por este tutorial que es muy didáctico, vale decir también que me ha sido de mucha ayuda para la tarea de la universidad…jeje.
No enserio he recordado y practicado bastante con estos temas que has posteado sigue así, eso es lo que necesitamos personas que colaboren con el conocimiento humano.
Al llamar el formulario de usuarios como lo haces tu, el help_text y el nombre del campo en la vista están en ingles.
¿Cómo pasarlo a español?
MUCHISIMAS GRACIAS Me salvaste la vida para un proyecto en Django de Ventas
Te Debo una Sigue así Saludos desde México Y de un niño de 14 años 😀
hola saergio me sale este error me podrias ayudar
importError at /usuario/nuevo
No module named principal
Request Method: GET
Request URL: http://127.0.0.1:8000/usuario/nuevo
Django Version: 1.4.2
Exception Type: ImportError
Exception Value:
No module named principal
Exception Location: C:\Python27\lib\site-packages\django\utils\importlib.py in import_module, line 35
Python Executable: C:\Python27\python.exe
Python Version: 2.7.3
Python Path:
[”,
‘C:\\autentication’,
‘C:\\Windows\\system32\\python27.zip’,
‘C:\\Python27\\DLLs’,
‘C:\\Python27\\lib’,
‘C:\\Python27\\lib\\plat-win’,
‘C:\\Python27\\lib\\lib-tk’,
‘C:\\Python27’,
‘C:\\Python27\\lib\\site-packages’,
‘C:\\Python27\\lib\\site-packages\\PIL’]
Server time: Sat, 1 Dec 2012 17:57:49 -0600
Mira, eso te puede estar pasando por que no agregaste principal como aplicación en el settings.py:
INSTALLED_APPS = (
‘django.contrib.auth’,
……todas las apps
‘principal’,
)
Cuando me encontraba con este tipo de errores lo que hacía era verificar como esta hecho en el repositorio y comparar línea por línea… también puede ser que te faltó importar algo al principio de los archivos.