Desarrollo de Ecommerce con Django (parte 3)
Published: 2024-04-01 20:40:39

Este tutorial cubre los siguientes puntos:

- Uso de django-bootstrap5.
- Formularios de registro de usuario e inicio de sesión.
- Flujo de inicio y cierre de sesión.

**Paso 1: Instalación de django-bootstrap5**

Django-bootstrap5 complementa el uso de Bootstrap 5 en proyectos Django al proporcionar una integración más estrecha a través de etiquetas de plantilla y utilidades específicas. Esto simplifica la incorporación de estilos y componentes de Bootstrap en las plantillas HTML de Django, lo que resulta en interfaces de usuario consistentes y receptivas. Al utilizar Django-bootstrap5 junto con Bootstrap 5 a través de un CDN, se aprovechan tanto la conveniencia y velocidad de carga de los activos estáticos como las ventajas de la integración profunda de Django-bootstrap5 en proyectos Django.

Para instalarlo debemos ejecutar en la terminal el comando:

```poetry add django-bootstrap5```

Además, debemos agregarlo en la configuración de INSTALLED_APPS del proyecto. Abre el archivo eelaecommerce/settings.py y busca la lista INSTALLED_APPS. Añade la aplicación al final de esta lista. Debería verse así:

```
INSTALLED_APPS = [
    ...
    'django_bootstrap5'
]
```

**Paso 2: Creación del formulario de registro de usuario**

- Definir el formulario de registro:

Primero, necesitamos definir el formulario de registro (SignUp) en Django. Crea el archivo `forms.py` en la aplicación "store" y agrega el siguiente código:

```
from django import forms

class SignUpForm(forms.Form):
    username = forms.CharField(label="Usuario:", min_length=6, max_length=12, required=True, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Ej.: gvillacis'}))
    nombre = forms.CharField(label="Nombre:", max_length=50, required=True, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Ej.: Gabriel'}))
    apellido = forms.CharField(label="Apellido:", max_length=50, required=True, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Ej.: Villacis'}))
    email = forms.EmailField(label="Email:", max_length=75, required=True, widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Ej.: gvillacis@hotmail.com'}))
    password1 = forms.CharField(label="Contraseña:", min_length=8, max_length=16, required=True, widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Ej.: de*738Hoewiux!$'}))
    password2 = forms.CharField(label="Repita la contraseña:", min_length=8, max_length=16, required=True, widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Ej.: de*738Hoewiux!$'}))
    
    def clean(self):
        cleaned_data = super(SignUpForm, self).clean()
        password = cleaned_data.get("password1")
        confirm_password = cleaned_data.get("password2")

        if password != confirm_password:
            self.add_error('password2', "Las contraseñas no coinciden.")

        return cleaned_data

```

- Crear la plantilla HTML:

Ahora, necesitamos crear una plantilla HTML para renderizar el formulario. Crea el archivo `signup.html` en el directorio de plantillas de la aplicación "store" y agrega el siguiente código:

```
{% load django_bootstrap5 %}
{% bootstrap_css %}
{% bootstrap_javascript %}

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EELA Ecommerce - Registro de Usuario</title>
</head>
<body>
    <div class="container">
        <div class="row h-100 justify-content-center align-items-center">        
            <div class="col-md-4">
                <h3 class="text-center">Registro de Usuario</h3>

                {% bootstrap_messages %}

                <form action="{% url 'signup' %}" method="post" novalidate>
                    {% csrf_token %}

                    {% bootstrap_form sign_up_form %}

                    {% bootstrap_button "Registrar" button_type="submit" size="sm"  %}
                    {% bootstrap_button "Borrar" button_type="reset" size="sm" button_class="btn-outline-secondary" %}
<a href="{% url 'home' %}" class="btn btn-link">Ir a la Tienda</a>
                </form>
            </div>
        </div>        
    </div>
</body>
</html>
```
- Configurar la vista:

Ahora, necesitamos crear una vista en Django para procesar el formulario. Puedes agregar el siguiente código a tu archivo `views.py`:

```
...
...

from django.shortcuts import render, redirect
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
from .forms import SignUpForm
from django.contrib import messages
from datetime import datetime

def do_signup(request):
    if request.method == "POST":        
        sign_up_form = SignUpForm(request.POST)
        if sign_up_form.is_valid():
            username = sign_up_form.cleaned_data.get('username')
            password = sign_up_form.cleaned_data.get('password1')
            nombre = sign_up_form.cleaned_data.get('nombre')
            apellido = sign_up_form.cleaned_data.get('apellido')
            email = sign_up_form.cleaned_data.get('email')
            
            if User.objects.filter(username=username).exists():
                messages.error(request, "El username ingresado ya está siendo utilizado!")
            else:            
                nuevo_usuario = User(
                    username=username,
                    password=make_password(password),
                    is_superuser=False,
                    first_name=nombre,
                    last_name=apellido,
                    email=email,
                    is_staff=False,
                    is_active=True,
                    date_joined=datetime.now()
                )
                nuevo_usuario.save()
                                
                return redirect('success_signup')
    else:
        sign_up_form = SignUpForm()        
    
    return render(request, 'signup.html', {'sign_up_form': sign_up_form})
```

- Agregar la URL en el archivo de URLs de la aplicación:

Ahora necesitamos configurar una URL para nuestra vista. Agrega el siguiente código a tu archivo urls.py de la aplicación "store":

```
from django.urls import path
from . import views

urlpatterns = [
  # Otras rutas
  path('signup/', views.do_signup, name='signup')
]
```

En vista de que al final del proceso de registro se quiere mostrar una pantalla de éxito. Se debe incorporar el redireccionamiento hacia esa pantalla.

- Agregar la vista de éxito en views.py:

Necesitamos definir la vista success_signup en `views.py` para mostrar una página de éxito después de que el usuario se haya registrado correctamente. Puedes agregar el siguiente código:

```
def success_signup(request):
    return render(request, 'success_signup.html')
```

- Configurar la URL para la vista de éxito en urls.py:

Después de definir la vista success_signup, necesitamos configurar una URL para ella en el archivo `urls.py` de la aplicación. Puedes agregar el siguiente código:

```
from django.urls import path
from . import views

urlpatterns = [
  # Otras rutas
  path('success-signup/', views.success_signup, name='success_signup'),
]
```

Y finalmente, necesitamos crear una plantilla HTML para renderizar la pantalla de éxito. Crea el archivo `success_signup.html` en la carpeta de plantillas y Usa el siguiente código:

```
{% load django_bootstrap5 %}
{% bootstrap_css %}
{% bootstrap_javascript %}

<!DOCTYPE html>
<html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>EELA Ecommerce - Registro Exitoso</title>
    </head>
    <body>
        <div class="vh-100 d-flex justify-content-center align-items-center">
            <div class="card col-md-4 bg-white shadow-md p-5">
                <div class="mb-4 text-center">
                    <svg xmlns="http://www.w3.org/2000/svg" class="text-success" width="75" height="75"
                        fill="currentColor" class="bi bi-check-circle" viewBox="0 0 16 16">
                        <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z" />
                        <path
                            d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z" />
                    </svg>
                </div>
                <div class="text-center">
                    <h1>Registro exitoso!</h1>
                    <p>EELA Ecommerce te da la bienvenida a una fantástica experiencia de compras.</p>
                    <a class="btn btn-outline-info" href="#">Iniciar sesión</a>
                    <a class="btn btn-outline-success" href="{% url 'home' %}">Ir a la Tienda</a>
                </div>
            </div>
    </body>
</html>

```

Para probar el flujo de registro completo, asegúrate de que tus rutas y vistas estén configuradas correctamente y ejecuta tu servidor Django. Luego, accede a la URL `http://localhost:8000/signup` en tu navegador para iniciar el proceso de registro.

Una vez que completes el formulario y hagas clic en "Registrar", deberías ser redirigido automáticamente a la página de éxito en `http://localhost:8000/success-signup/`

**Paso 3: Creación del formulario de inicio de sesión**

A continuación, vamos a crear el flujo de inicio de sesión utilizando el formulario AuthenticationForm de Django:

- Definir la vista de Inicio de Sesión en `views.py`:

Primero, necesitamos definir una vista en Django para manejar el proceso de inicio de sesión. Agrega el siguiente código al archivo `views.py`:

```
...
...
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import authenticate, login

def do_signin(request):
    if request.method == 'POST':
        form = AuthenticationForm(request, data=request.POST)
        if form.is_valid():
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            
            user = authenticate(username=username, password=password)
            if user is not None:
                login(request, user)
                return redirect('home')
            else:
                messages.error(request, 'Usuario o contraseña inválidos.')
        else:
            messages.error(request, 'Usuario o contraseña inválidos.')        
    
    form = AuthenticationForm()
    return render(request, 'signin.html', {'signin_form': form})

```

- Crear la plantilla HTML:

Ahora, necesitamos crear una plantilla HTML para renderizar el formulario de inicio de sesión. Crea el archivo `signin.html` en tu directorio de plantillas y agregar el siguiente código:

```
{% load django_bootstrap5 %}
{% bootstrap_css %}
{% bootstrap_javascript %}

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EELA Ecommerce - Iniciar Sesión</title>
</head>
<body>

    <div class="container">
        <div class="row h-100 justify-content-center align-items-center">        
            <div class="col-md-4">
                <h3 class="text-center">Iniciar Sesión</h3>

                {% bootstrap_messages %}
                
                <form action="{% url 'signin' %}" method="post" class="form" novalidate>
                    {% csrf_token %}

                    {% bootstrap_form signin_form %}

                    {% bootstrap_button "Iniciar sesión" button_type="submit" size="sm" %}
                    {% bootstrap_button "Borrar" button_type="reset" size="sm" button_class="btn-outline-secondary" %}
<a href="{% url 'home' %}" class="btn btn-link">Ir a la Tienda</a>
                </form>                
            </div>
        </div>        
    </div>
</body>
</html>
```

- Configurar la URL para la vista de Inicio de Sesión en `urls.py`:

Después de definir la vista de inicio de sesión, necesitamos configurar una URL para ella en el archivo `urls.py` de la aplicación. Puedes agregar el siguiente código:

```
from django.urls import path
from . import views

urlpatterns = [
  # Otras rutas
  path('signin/', views.do_signin, name='signin')
]
```

¡Eso es todo! Ahora deberías tener un flujo de inicio de sesión funcional utilizando el formulario AuthenticationForm de Django. Cuando accedas a la URL `http://localhost:8000/signin` en tu navegador, verás el formulario de inicio de sesión renderizado. Una vez que inicies sesión correctamente, serás redirigido a la página de inicio.

**Paso 4: Cierre de sesión**

Ahora veremos como implementar la funcionalidad de cierre de sesión (logout) en Django:

- Definir la Vista de Cierre de Sesión en `views.py`:

Primero, necesitamos definir una vista en Django para manejar el proceso de cierre de sesión. Agrega el siguiente código a tu archivo `views.py`:

```
...
...
from django.contrib.auth import logout


def do_logout(request):
    logout(request)
    return redirect('signin')

```

- Configurar una URL para la vista de Cierre de Sesión en `urls.py`:

Después de definir la vista de cierre de sesión, necesitamos configurar una URL para ella en el archivo `urls.py` de la aplicación, de la siguiente forma:

```
from django.urls import path
from . import views

urlpatterns = [
  # Otras rutas
  path('logout/', views.do_logout, name='logout')
]
```

¡Y eso es todo! Ahora deberías tener la funcionalidad de cierre de sesión implementada en tu aplicación Django. Ejecuta en tu navegador la URL `http://localhost:8000/logout` y debes ser redirigido a la página de inicio de sesión.

**Da clic [aquí](https://dev.to/villacisg93/desarrollo-de-ecommerce-con-django-parte-4-3pp6) para ir a la cuarta parte de este tutorial.**