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
:
- create_item: Cria um item na lista.
- 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.