DEV Community

Cover image for Crud En Django con Slug, 2022
Rodrigo Lazo
Rodrigo Lazo

Posted on

Crud En Django con Slug, 2022

Hoy vamos a crear un crud(Create, Read, Update, Delete) básico en el framework Django

Requisito
Tener Python instalado, en caso de no tenerlo descargue e instale desde su página: https://www.python.org/

Instalación
Comenzamos instalando el entorno virtual, para ello abrimos cmd(símbolo del sistema) e ingresamos el siguiente comando pip install virtualenv, una vez instalada de manera global comenzamos con los siguientes paso

  1. Creamos una carpeta la cual contendrá el proyecto, en mi caso se llamara django-crud

  2. Abrimos cmd y nos ubicamos en la carpeta creada

Image description

  1. Creamos el entorno virtual con el comando virtualenv env, esto nos sirve para la instalación de dependencias que requiere este crud.

Image description

  1. Activamos el entorno virtual con el comando .\env\Scripts\activate

Image description

  1. Instalamos Djando con el siguiente comando pip install Django==4.0

  2. Creamos el proyecto con el siguiente comando django-admin startproject NombreProyecto, en mi caso se llamará mycrud

Image description

  1. Accedemos ala carpeta del proyecto _cd mycrud
  2. Creamos una aplicación con el comando py manage.py startapp crud
  3. Levantamos el proyecto con el comando py manage.py runserver, accedemos ala web http://localhost:8000/

Image description

Configuración settings.py
Abrimos nuestro proyecto en nuestro editor de texto Favorito, en mi caso estaré usando Visual Studio Code y abrimos el archivo _settings.py _ para configurar algunas opciones

Image description

  1. Definimos nuestra aplicación en INSTALLED_APPS agregando el nombre 'crud.apps.CrudConfig',

Image description

models.py
Abrimos el archivo models.py y creamos nuestro modelo de la siguiente manera

from django.db import models
from django.utils.text import slugify

class Developer(models.Model):
    name = models.CharField(max_length=50,null=True)
    age = models.IntegerField(null=True,blank=True)
    skill = models.CharField(max_length=50,null=True)
    slug = models.SlugField(null=True, blank=True)

    class Meta:
        verbose_name = 'Developer'
        verbose_name_plural = 'Developers'

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        if self.slug == None:
            slug = slugify(self.name)

            has_slug = Developer.objects.filter(slug=slug).exists()
            count = 1
            while has_slug:
                count += 1
                slug = slugify(self.name) + '-' + str(count) 
                has_slug = Developer.objects.filter(slug=slug).exists()

            self.slug = slug
        super().save(*args, **kwargs)
Enter fullscreen mode Exit fullscreen mode

En este modelo se puede observar sus 4 variables de registro como name, age, skill, slug, este último slug es la variable que generara nombres únicos para cada registro el cual podrá remplazar al id

Creamos la migración del modelo con el comando python manage.py makemigrations

Image description

Y Migramos con el comando python manage.py migrate

CRUD Ingresar views.py
Para hacer el ingresar en Django nos situamos en archivo views.py y ingresamos el siguiente código

from django.shortcuts import render, redirect
from .models import *
from django.contrib import messages

# CRUD DEVELOPERS

#------ Create ------

def createDev(request):
    name = request.POST['nameInput']
    age = request.POST['ageInput']
    skill = request.POST['skillInput']

    developer = Developer.objects.create(
        name=name, age=age, skill=skill)
    messages.success(request, 'User: ' + name +' ¡Save Success !')
    return redirect('/')
Enter fullscreen mode Exit fullscreen mode

En este código se importan algunos elementos propios de Djando que facilitaran la creación del crud, además de mensajes tipo request para su interacción.

urls.py
Para direccionar las funciones de nuestra vista creamos un archivo con el nombre urls.py bajo la carpeta crud y ingresamos el siguiente código

from django.urls import path
from . import views

urlpatterns = [

    # Urls Developers
    path('register/', views.createDev),

]
Enter fullscreen mode Exit fullscreen mode

y en nuestra urls.py principal que esta baja la carpeta de mycrud se tiene el código de la siguiente manera, misma que indica referencia ala dirección urls de la aplicación crud

Image description

Platilla
una platilla es la base en la cual se trabajará el proyecto; Bajo la carpeta crud creamos una carpeta llamada templates en cuál contendrá todos nuestros documentos html y creamos el archivo base.html
con la siguiente estructura

<!DOCTYPE html>
<html lang="en">

<head>
    {% load static %}
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %} {% endblock %}</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
        integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>

<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-dark">
        <a class="navbar-brand" href="#" style="color: white">Developers</a>

    </nav>
    <div class="container py-4">
        {% block body %}

        {% endblock %}
    </div>
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
        integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.min.js"
        integrity="sha384-w1Q4orYjBQndcko6MimVbzY0tgp4pWB4lZ7lr30WKz0vr/aWKhXdBNmNb5D92v7s" crossorigin="anonymous">
    </script>
    <script src="{% static 'js/bntButton.js' %}"></script>
</body>

</html>
Enter fullscreen mode Exit fullscreen mode

para los archivos css y javascript, bajo el archivo *crud * se crea una carpeta de nombre static y se tiene los siguientes archivos:

Image description
con la siguiente información de cada archivo

style.css

th,
td {
  text-align: center;
  vertical-align: middle;
}

Enter fullscreen mode Exit fullscreen mode

bntButton.js

(function () {

    const btnDelete = document.querySelectorAll(".btnDelete");

    btnDelete.forEach(btn => {
        btn.addEventListener('click', (e) => {
            const confirmacion = confirm('¿Confirm to delete?');
            if (!confirmacion) {
                e.preventDefault();
            }
        });
    });

})();
Enter fullscreen mode Exit fullscreen mode

Formulario
Nuestro formulario será la vista en la cual se podrá realizar el registro, para este ejemplar se ingresara desarrolladores o programadores con nombre, edad y habilidad o lenguaje de programación que maneja.
Para ello creamos un documento html en la carpeta templates en este caso se llamará index.html con la siguiente información

{% extends "./base.html" %}

{% block title %} Form {% endblock %}

{% block body %}
<div class="row">
    <div class="col-sm-12 col-md-6 col-lg-4 col-xl-4">
        {% if messages %}
        {% for message in messages %}
        <div class="alert alert-dismissible alert-success">
            <button type="button" class="close" data-dismiss="alert">&times;</button>
            <strong class="text-dark">{{ message }}</strong>
        </div>
        {% endfor %}
        {% endif %}
        <h2>Form</h2>
        <div class="card">
            <div class="card-body">
                <form action="/register/" method="POST">{% csrf_token %}
                    <div class="form-group">
                        <input type="text" id="nameInput" name="nameInput" class="form-control" placeholder="Name"
                            required>
                    </div>
                    <div class="form-group">
                        <input type="number" id="ageInput" name="ageInput" class="form-control" placeholder="Age"
                            maxlength="50" required>
                    </div>
                    <div class="form-group">
                        <input type="text" id="skillInput" name="skillInput" class="form-control" min="1" max="9"
                        placeholder="Skill" required>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-info btn-block text-white">Save</button>
                    </div>
                </form>
            </div>
        </div>
    </div>

</div>
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

Levantamos el servicio en cmd python manage.py runserver
y tenemos el siguiente resultado

Image description

Realizamos un registro
Image description
Resultado
Image description

Ahora bien nos toca mostrar, editar y eliminar para ello realizamos los siguientes cambios en cada uno de los archivos que les menciona.
views.py

from django.shortcuts import render, redirect
from .models import *
from django.contrib import messages


# CRUD DEVELOPERS

#------ Create ------

def createDev(request):
    name = request.POST['nameInput']
    age = request.POST['ageInput']
    skill = request.POST['skillInput']

    developer = Developer.objects.create(
        name=name, age=age, skill=skill)
    messages.success(request, 'User: ' + name +' ¡Save Success !')
    return redirect('/')


#------ List ------
def listDev(request):
    developers = Developer.objects.all()
    return render(request, "index.html", {"developers": developers})


#------ Edit ------
def editDev(request, slug):
    developer = Developer.objects.get(slug=slug)

    name = request.POST.get('nameInput')
    age = request.POST.get('ageInput')
    skill = request.POST.get('skillInput')
    if request.method == 'POST':

        developer.name = name
        developer.age = age
        developer.skill = skill
        developer.save()
        messages.success(request, 'User: ' + name +' ¡Edit Success!')
        return redirect('/')

    return render (request, "edit.html", {"developer": developer})

#------ Delete ------
def deleteDev(request, slug):
    developer = Developer.objects.get(slug=slug)

    developer.delete()
    messages.success(request, '¡Developer Deleted!')
    return redirect('/')  
Enter fullscreen mode Exit fullscreen mode

urls.py
El que esta bajo la carpeta crud

from django.urls import path
from . import views

urlpatterns = [

    # Urls Developers
    path('', views.listDev),
    path('register/', views.createDev),
    path('edit/<slug:slug>', views.editDev, name='editUrl'),
    path('delete/<slug:slug>', views.deleteDev, name='deleteUrl'),

]
Enter fullscreen mode Exit fullscreen mode

index.html

{% extends "./base.html" %}

{% block title %} Form {% endblock %}

{% block body %}
<div class="row">
    <div class="col-sm-12 col-md-6 col-lg-4 col-xl-4">
        {% if messages %}
        {% for message in messages %}
        <div class="alert alert-dismissible alert-success">
            <button type="button" class="close" data-dismiss="alert">&times;</button>
            <strong class="text-dark">{{ message }}</strong>
        </div>
        {% endfor %}
        {% endif %}
        <h2>Form</h2>
        <div class="card">
            <div class="card-body">
                <form action="/register/" method="POST">{% csrf_token %}
                    <div class="form-group">
                        <input type="text" id="nameInput" name="nameInput" class="form-control" placeholder="Name"
                            required>
                    </div>
                    <div class="form-group">
                        <input type="number" id="ageInput" name="ageInput" class="form-control" placeholder="Age"
                            maxlength="50" required>
                    </div>
                    <div class="form-group">
                        <input type="text" id="skillInput" name="skillInput" class="form-control" min="1" max="9"
                        placeholder="Skill" required>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-info btn-block text-white">Save</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <div class="col-sm-12 col-md-6 col-lg-8 col-xl-8">
        <h1>Developer List</h1>
        <div class="table-responsive py-2">
            <table class="table table-striped table-hover">
                <thead class="bg-info">
                    <tr class="text-light">
                        <th>#</th>
                        <th>Name</th>
                        <th>Age</th>
                        <th>Skills</th>
                        <th colspan="2"> options</th>
                    </tr>
                </thead>
                <tbody>
                    {% for dev in developers %}
                    <tr>
                        <td>{{forloop.counter}}</td>
                        <td>{{dev.name}}</td>
                        <td>{{dev.age}}</td>
                        <td>{{dev.skill}}</td>
                        <td><a href="{%  url 'editUrl' dev.slug %}" class="btn btn-info">Edit</a></td>
                        <td><a href="{%  url 'deleteUrl' dev.slug %}" class="btn btn-danger btnDelete">Delete</a></td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
</div>
{% endblock %}

Enter fullscreen mode Exit fullscreen mode

Para el editar creamos otro documento html con el nombre de edit.html, esta bajo la carpeta templates y ingresamos el siguintes codigo

{% extends "./base.html" %}

{% block title %} Edit {% endblock %}

{% block body %}
<div class="row">
    <div class="col-md-4 offset-md-4">
        <h2>Edit</h2>
        <div class="card">
            <div class="card-body">
                <form action="{% url 'editUrl' developer.slug %}"  method="POST">
                    {% csrf_token %}
                    <div class="form-group">
                        <input type="text" id="nameInput" name="nameInput" value="{{developer.name}}" class="form-control" placeholder="Name"
                            required>
                    </div>
                    <div class="form-group">
                        <input type="number" id="ageInput" name="ageInput" value="{{developer.age}}" class="form-control" placeholder="Age"
                            maxlength="50" required>
                    </div>
                    <div class="form-group">
                        <input type="text" id="skillInput" name="skillInput" value="{{developer.skill}}" class="form-control"
                        placeholder="Skill"required>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-success btn-block text-white">Edit</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
{% endblock %}
Enter fullscreen mode Exit fullscreen mode

Con esos cambios ya se tiene el CRUD completo, a continuacion les muestro como queda.
Image description

Creamos uno
Image description

Editamos uno
Image description
Image description
Slug
se puede ver lo que hace el slug que remplaza nuestro id por una valor unico en este caso el nombre, esto ayuda mucho para temas de seguridad ya que con esto se oculta el id ala que pertencese el registro
Image description

Eliminamos uno
Image description

Image description

Espero que les ayude...
Fuetes:
https://docs.djangoproject.com/en/4.0/
https://www.youtube.com/watch?v=iQcJPeCcjNo&t=1585s
https://www.youtube.com/watch?v=uSbDMs7Y9yI&t=189s

Discussion (0)