Django Users
Django nos provee de un modelo y un sistema completo de autenticación de usuarios.
ESTO NOS VIENDE DE LA PUTA MADRE. Es muy útil e intuitivo, de hecho, quedaras lol.
La Idea
La idea es hacer un sitio en donde el usuario pueda ver su perfil.
Además, crearemos una forma de agregar comentarios a productos.
Estaremos usando el proyecto anterior ProyectoDjango
.
Si no tienes el proyecto, tienes dos opciones:
- Puedes ver todos los capítulos anteriores y recrear el proyecto (recomendado)
- Descargar
ProyectoDjango
(no recomendado)
Recuerda
- Crear un entorno virtual de Python.
- Activar el entorno virtual de Python.
- Instalar Django.
Manejo del inicio de sesión, registro y logout
Para esto, crearemos una nueva aplicación, asi mantenemos un orden. La app la llamare autenticacion
...
py manage.py startapp autenticacion
En views.py
de la aplicación autenticacion
, creare las siguientes vistas:
| from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from .forms import SignupForm, LoginForm
from django.contrib.auth.decorators import login_required
# Create your views here.
# 👇 uso de un decorador
@login_required # 👈 se obliga al usuario a tener una sesion activa para ver esta vista
def index(request):
return render(request, "autenticacion/index.html")
|
El decorador permite que Django se encargue de las redirecciones en el caso de que un usuario no tenga sesión activa. Si la tiene, simplemente devuelve la vista.
| def registrar(request):
# 👇 si el usuario tiene sesion activa...
if request.user.is_authenticated:
return redirect('autenticacion:index') # entonces lo mandamos al inicio de la app
form = SignupForm(request.POST)
if request.method == 'POST':
if form.is_valid():
form.save()
return redirect('autenticacion:login')
return render(request, 'autenticacion/signup.html', {'form': form})
|
El formulario hereda de otro, por lo que ese "padre" hereda la lógica de registro del usuario.
Al final entendamos que un Usuario es solo un registro. Y Django se encargará de lo más tedioso.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | def iniciarsesion(request):
if request.user.is_authenticated:
return redirect('autenticacion:index')
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
# 👇 la funcion authenticate nos permite validar un usuario
user = authenticate(request, username=username, password=password)
# 👇 si la funcion devuelve un 'Usuario', significa que las credenciales son correctas
if user:
# 👇 la funcion login inicia la sesion del usuario
login(request, user)
return redirect('autenticacion:index') # lo mandamos al perfil
else:
form = LoginForm()
return render(request, 'autenticacion/login.html', {'form': form})
|
| @login_required # 👈 obviamente, un usuario sin sesion no puede terminar una
def cerrarsesion(request):
logout(request) # cerramos la sesion del usuario
return redirect('autenticacion:login') # lo mandamos al sitio de inicio de sesion
|
Debemos crear el archivo forms.py
para definir los formularios...
Primero, importamos lo necesario:
| from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User # Modelo de Django que contiene a los usuarios
|
Luego, creamos nuestro formulario de registro:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 | # 👇 nuestro formulario de registro hereda de UserCreationForm, que tiene toda la logica.
class SignupForm(UserCreationForm):
class Meta:
model = User
# 👇 declaramos que campos deseamos mostrar en el formulario.
fields = ['username', 'email', 'password1', 'password2']
# username, password1 y password2 SON OBLIGATORIOS.
# 👇 definimos las clases y tipos de entrada
widgets = {
"username": forms.TextInput(
attrs={
"class": "form-control",
}
),
"email": forms.EmailInput(
attrs={
"class": "form-control"
}
),
"password1": forms.PasswordInput(
attrs={
"class": "form-control"
}
),
"password2": forms.PasswordInput(
attrs={
"class": "form-control"
}
),
}
|
| class LoginForm(forms.Form):
username = forms.CharField(widget=forms.TextInput(attrs={"class": "form-control"}))
password = forms.CharField(widget=forms.PasswordInput(attrs={"class": "form-control"}))
|
Definición de rutas
Creamos nuestro archivo urls.py
dentro de la app autenticacion
y definimos las rutas que usaremos:
| from django.urls import path
import autenticacion.views as app
app_name = "autenticacion"
urlpatterns = [
path('', app.index, name="index"),
path('signup/', app.registrar, name="signup"),
path('login/', app.iniciarsesion, name="login"),
path('logout/', app.cerrarsesion, name="logout"),
]
|
Recuerda que es importante definir la variable app_name
y definir las variables name
a cada ruta.
Creando las templates
Ahora, necesitamos el front-end para poder visualizar nuestro sistema de autenticación.
Para ello, creamos la carpeta autenticacion
dentro de templates
, tal que:
- templates/
- autenticacion/
- index.html
- login.html
- signup.html
Index
La página index actuará como el perfil del usuario, allí se podrá ver información sobre el usuario:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | {% extends 'base.html' %}
{% block title %}Auth{% endblock %}
{% block content %}
<div class="container">
<!-- la variable 'user' siempre esta disponible, por defecto es un usuario anonimo -->
<!-- si no hay sesion activa, sus campos no tendran valores -->
<h1>Bienvenido, {{ user.username }}!</h1>
<h5>Te registraste el {{ user.date_joined }}</h5>
<h5>Actualmente, {% if user.is_staff %}eres parte del staff!{% else %}no eres parte del staff.{% endif %}{% if user.is_superuser %} Y eres un Superusuario 👷♂️{% else %} Comun y corriente.{% endif %}</h5>
<h5>Tu correo registrado es {{ user.email }}</h5>
<!-- como puedes observar, es simplemente un modelo mas, y con ello podemos acceder a sus columnas -->
<hr>
<!-- desde no se que version de Django, para el Logout es necesario con POST (y no GET) -->
<form action="{% url 'autenticacion:logout' %}" method="post">
{% csrf_token %}
<button class="btn btn-danger" type="submit">Cerrar sesión</button>
</form>
</div>
{% endblock %}
|
Login
La template login permite que el usuario inicie una sesión a través del formulario de inicio de sesión.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | {% extends 'base.html' %}
{% block title %}Log in - Auth{% endblock %}
{% block content %}
<div class="container">
<h1>Login</h1>
<form method="POST">
{% csrf_token %}
{{ form }}
<br>
<button class="btn btn-success" type="submit">Iniciar sesión</button>
¿No tienes una cuenta? <a href="{% url 'autenticacion:signup' %}">Registrate aquí</a>.
</form>
</div>
{% endblock %}
|
Signup
Igualmente, no tiene mucha ciencia...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | {% extends 'base.html' %}
{% block title %}Sign up - Auth{% endblock %}
{% block content %}
<div class="container">
<h1>Signup</h1>
<form method="POST">
{% csrf_token %}
{{ form }}
<br>
<button class="btn btn-success" type="submit">Registrarse</button>
¿Ya tienes una cuenta? <a href="{% url 'autenticacion:login' %}">Inicia sesión aquí</a>.
</form>
</div>
{% endblock %}
|
Integración con la template base.html
Es normal que en el navbar (o barra de navegación) se encuentren los típicos botones para iniciar sesión, registrarse y ver el perfil de un usuario. En este caso, no será la excepción.
Para ello, nos dirigiremos a la template base.html
y la mejoraremos.
Esto se hace en la etiqueta header
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | ...
</ul>
</div>
<div class="text-end">
<!-- user tiene sus metodos, que podemos usar. El siguiente metodo permite saber si el usuario esta autentificado. si no, entonces mostramos los botones comunes -->
{% if user.is_authenticated %}
<!-- si el usuario tiene una sesion activa, esta variable es True -->
<a href="{% url 'autenticacion:index' %}" class="btn btn-primary">Perfil</a>
{% else %}
<!-- si no hay sesion, es usuario anonimo -->
<a href="{% url 'autenticacion:login' %}" class="btn btn-success">Login</a>
<a href="{% url 'autenticacion:signup' %}" class="btn btn-warning">Sign-up</a>
{% endif %}
</div>
</div>
</nav>
</header>
...
|
Configuración de variables de sesión
Django nos permite indicar las rutas para el control del comportamiento del sistema de usuarios. Estas variables se deben definir en settings.py
de nuestro proyecto:
| # Login
LOGIN_URL = "autenticacion:login" # Si el usuario topa con una vista que pide inicio de sesion, esta variable le indica donde debe Iniciar sesion
LOGIN_REDIRECT_URL = "autenticacion:index" # Si el usuario inicia sesion (sin redireccion del caso de arriba) lo dirige a la vista index de la app autenticacion
LOGOUT_REDIRECT_URL = "tienda:index" # Si el usuario cierra sesion, lo manda a la vista index de la app tienda
|
Estas variables indican que debe hacer Django en los casos mencionados.
Finalmente, definimos la ruta principal
Ahora es el turno del archivo urls.py
dentro de la carpeta del proyecto (ProyectoDjango/urls.py
):
| urlpatterns = [
...
# 👇 definimos la nueva ruta para la aplicacion
path('cuenta/', include("autenticacion.urls", namespace="autenticacion")),
]
|
Y eso es todo.
Ahora ya tienes usuarios que pueden registrase, iniciar sesión, cerrar sesión, etc. La lógica se la dejamos a Django.
✨ES UNA PUTA MARAVILLA ❤.