Curso Django

El web framework para perfeccionistas

Desarrollo rápido y limpio basado en Python

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

nuevo_usuario()

nuevo_usuario()

Luego la siguiente plantilla (nuevousuario.html):

nuevousuario.html

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:

http://127.0.0.1:8000/usuario/nuevo

http://127.0.0.1:8000/usuario/nuevo

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

ingresar()

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

noactivo.html

noactivo.html

nousuario.html

nousuario.html

ingresar.html

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).

http://127.0.0.1:8000/ingresar/

http://127.0.0.1:8000/ingresar/

Usuario no activo

Usuario no activo

Error de autenticación

Error de autenticación

error 404

error 404

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:

privado()

privado()

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:

ingresar() mejorado

ingresar() mejorado

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

privado.html

privado.html

Nuestro resultado sería:

acceso restringido

acceso restringido

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:

cerrar()

cerrar()

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:

urls.py

urls.py

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

Siguiente capítulo: Despliegue en el servidor web

Sergio Infante MonteroSergio Infante Montero para Maestros del Web.
Agrega tu comentario | Enlace permanente al artículo

Síguenos en: Twitter @maestros | Facebook Fan page

37 comentarios

Comentarios

  1. martin algañaraz

    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

  2. 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/)

    1. martin algañaraz

      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.

  3. Hmmm genial todo esta super !! :3

  4. …Sergio te felicito, muy buen texto, bien claro, preciso…excelente!!!…muchas gracias

  5. Jesus

    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.

    1. 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 :)

    2. Xapusoft

      ¿Eso quiere decir que la siguiente clase será la última?

  6. Ricky

    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?

    1. Hola Ricky, pues algo estaremos tramando, si nos sigues por Twitter ahi te enteraras de primera mano :)

  7. Jesus

    Muchas gracias Sergio por atender mi pregunta esperare con muchas ansias el tema de la siguiete semana =D

  8. Ray

    Aprender con Sergio, nunca fue más facil y rápido…!

  9. alvaro

    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?

    1. Samuel

      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.
      :D

    2. matias

      Puede ser tambien que estes redireccionando a ” / ” cuando se hace el login en ves de redireccionar a ” /privado “

    3. Samuel

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

  10. Edgar Hdez

    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.

    1. Diego

      Si Sergio,, vamos,,, te seguiremos en un tuto más avanzado …. gracias por estos temas

  11. jose carlos

    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

    1. Ya viene uno hecho :3

    2. 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 :)

  12. jesus baak

    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 !

    1. Quizas haya, esta en planes, pero despues de que esta guía este en versión descargable y disponible en Amazon para el Kindle

  13. Cristhian Amaya

    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!

    1. Gracias Cristhian por seguir el curso, aún falta el último capítulo (mañana).

  14. Esperamos Sergio I. M. =)

  15. jose carlos

    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 =)

  16. mario

    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??

  17. jonathan

    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.

  18. David Guerrero

    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

  19. Leandro

    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

    1. Leandro

      Perdon por esto, ya estaba en el capitulo.

  20. 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.

  21. 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?

  22. Victor

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

  23. 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

    1. Camilo Buitrago

      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.

Los comentarios de este post están cerrados. Si quieres seguir la discusión, debatir, criticar, sugerir o expandir el tema te invitamos a hacerlo en tu propio blog, en twitter o donde puedas publicar. No olvides enlazar a este post para que sigamos la conversación y se genere un trackback.