Django: TO DO LIST

Bem-vindo ao mundo da organização eficiente e da produtividade aprimorada! Em nosso dia a dia agitado, a capacidade de manter nossas tarefas e responsabilidades bem organizadas é mais importante do que nunca. É por isso que hoje vamos mergulhar na criação de um modelo de projeto intuitivo e personalizável, que não só nos ajudará a manter o controle de nossas atividades, mas também nos permitirá adaptar-se às mudanças com facilidade. Prepare-se para transformar a maneira como você gerencia suas listas de tarefas com nosso guia passo a passo para modelar seu próprio sistema de gerenciamento de tarefas.

Github

Depois de feitas as configurações iniciais e executado o projeto, vamos para a criação do nosso modelo e estrutura do projeto.

Modelando o Projeto

Vamos criar duas tabelas: TodoList e Status. A tabela Status serve para criar o drop-down de status, com opções como: "⛔️ a Fazer", "⚠️ Fazendo" e "✅ Finalizado". Em vez de deixar essas informações fixas em um simples array, optamos por criar uma tabela para que o usuário possa personalizar essas informações.

Na tabela TodoList, vamos criar um campo do tipo ForeignKey, relacionando com a tabela Status. O campo status terá um valor padrão (default=1), que será usado ao adicionar um item na lista.

Código do modelo

# myapp/models.py
from django.db import models

class Status(models.Model):
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name

class TodoList(models.Model):
    title = models.CharField(max_length=100)
    status = models.ForeignKey(Status, on_delete=models.CASCADE, related_name='status', to_field='id', default='1') 

    def __str__(self):
        return self.title

Formulário e Exibição no Template

No template HTML, teremos um formulário simples para adicionar um item na lista. O campo "title" será exibido, enquanto o campo "status" será excluído do formulário, pois já tem um valor padrão.

Código do formulário

# myapp/forms.py
from django import forms
from .models import TodoList

class TodoListForm(forms.ModelForm):
    class Meta:
        model = TodoList
        fields = ('title',)
        exclude = ('status',)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'form-control'

Funções de Criação e Exclusão

Criamos duas funções na views.py:

  1. create_item: Cria um item na lista.
  2. delete_item: Deleta um item da lista.
# myapp/views.py
from django.shortcuts import render, redirect, get_object_or_404
from .forms import TodoListForm
from .models import TodoList

def create_item(request):
    todo = TodoList.objects.all()
    if request.method == "POST":
        form = TodoListForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
    form = TodoListForm()
    context = {"form": form, 'todo': todo}
    return render(request, 'index.html', context)

def delete_item(request, id):
    todo = TodoList.objects.get(id=id)
    todo.delete()
    return redirect('index')

Configuração das Rotas

Em urls.py, configuramos as rotas para acessar nossas views.

# myapp/urls.py
from django.urls import path
from myapp import views

urlpatterns = [
    path('', views.create_item, name='create_item'),
    path('delete/<int:id>/', views.delete_item, name="delete"),
]

Template HTML

No template index.html, exibimos o formulário e a lista de tarefas. Aqui também utilizamos ícones da biblioteca Font Awesome.

<!-- myapp/templates/index.html -->
{% extends 'base.html' %} 
{% block title %}Página 1{% endblock %} 
{% block content %}
    <h2>Página 1</h2>
    <div class="p-5">
        <form class="d-flex gap-4 col-md-6" method="POST">
            {% csrf_token %}
            <button type="submit" class="btn btn-success"><i class="fa fa-plus"></i></button>
            {{form}}
        </form>
        <table class="table">
            <thead>
                <tr>
                    <th scope="col">Título</th>
                    <th scope="col">Status</th>
                    <th scope="col">Deletar</th>
                </tr>
            </thead>
            {% for el in todo %}
            <tbody>
                <tr class="table align-middle">
                    <th scope="row">{{el.title}}</th>
                    <th scope="row">{{el.status}}</th>
                    <th scope="row">
                        <a class="btn" href="{% url 'delete' el.id %}">
                            <i class="fa fa-trash link-danger"></i>
                        </a>
                    </th>
                </tr>
            </tbody>
            {% endfor %}
        </table>
    </div>
{% endblock %}

Configuração AJAX

Para deixar a página mais dinâmica, podemos utilizar AJAX para atualizar o título e o status dos itens sem precisar recarregar a página.

Atualizando o Título com AJAX

{% block scripts %}
<script type="text/javascript">
    $("div.title").click(function () {
        var data_id = $(this).attr("data-title");
        $("form#form-title" + data_id).removeClass('d-none');
        $("div#title" + data_id).addClass('d-none');

        $('button#edit' + data_id).on("click", function (e) {
            e.preventDefault();
            title = $('input#inputText' + data_id).val();

            $.ajax({
                type: 'GET',
                url: '{% url "update-item" %}',
                data: {'data_id': data_id, 'title': title},
                datatype: "json",
                success: function (data) {
                    if (data.status == "update-item") {
                        $("form#form-title" + data_id).addClass('d-none');
                        $("div#title" + data_id).removeClass('d-none');
                        $("#title" + data_id).html(data.title);
                    }
                }
            });
        });
    });
</script>
{% endblock %}

Atualizando o Status com AJAX

$("div.SelDiv select").on('change', function () {
    var data_id = this.id;
    var status_id = $(this).find('option').filter(':selected').val();

    $.ajax({
        type: 'GET',
        url: '{% url "update-status" %}',
        data: {'data_id': data_id, 'status_id': status_id},
        datatype: "json",
        success: function (data) {
            console.log(data);
        }
    });
});

Funções para Atualizar Status e Deletar Itens

# views.py

def update_item(request):  
    data_id = request.GET.get('data_id')
    title = request.GET.get('title')

    todo = get_object_or_404(TodoList, id=data_id)
    todo.title = title
    todo.save()

    data = {'status': 'update-item', 'title': title}
    return JsonResponse(data)

def update_status(request):  
    data_id = request.GET.get('data_id')
    status_id = request.GET.get('status_id')

    status = Status.objects.get(id=status_id)
    todo = get_object_or_404(TodoList, id=data_id)
    todo.status = status
    todo.save()

    data = {'status': status_id}
    return JsonResponse(data)

def delete_item(request):
    todo_id = request.GET.get('todo_id')
    todo = TodoList.objects.get(id=todo_id)
    todo.delete()

    data = {'status': 'delete'}
    return JsonResponse(data)

Conclusão

Com a estrutura de TodoList e Status configurada, você tem um sistema de gerenciamento de tarefas que pode ser facilmente personalizado e adaptado às suas necessidades. A integração com AJAX permite uma experiência mais dinâmica, sem recarregamento de página.

Olá,

Você precisa fazer login no sistema para comentar.

Entrar

Comentários

Total de Comentários: 0