Criando um Projeto Django para um Sistema de Registro de Defeitos

Preparação do Ambiente de Desenvolvimento

Este guia explica como configurar um projeto Django para uma aplicação web de registro de defeitos. Utilize o Python 2.7 e instale o Django 1.8.18 via pip para garantir todas as dependências. Execute o comando a seguir no terminal.

pip install django==1.8.18

Após a instalação, crie o projeto Django chamado "defeitos" usando o comando django-admin startproject defeitos. A estrutura resultante incluirá diretórios e arquivos essenciais.

Estrutura do Projeto Django

A organização do projeto segue o padrão do Django. Abaixo está um exemplo da estrutura de diretórios gerada.


defeitos/
    manage.py
    templates/
    defeitos/
        __init__.py
        settings.py
        urls.py
        wsgi.py

  • manage.py: Interface de linha de comando para gerenciar o projeto.
  • templates/: Armazena arquivos estáticos como CSS, JavaScript e ícones.
  • defeitos/: Diretório principal do projeto, contendo configurações e rotas.

Configurações do Projeto

Edite o arquivo settings.py para definir o banco de dados MySQL, o fuso horário e os diretórios de arquivos estáticos.


DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'defeitos_db',
        'USER': 'admin',
        'PASSWORD': 'senha_segura',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

TIME_ZONE = 'America/Sao_Paulo'

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'assets')
STATICFILES_DIRS = (
    'static/css',
    'static/bootstrap',
    'static/images',
    'static/js',
)

Criação de uma Aplicação Django

Para gerenciar a lógica de negócio, crie uma aplicação chamada "gestor" usando o comando python manage.py startapp gestor. Registre esta aplicação no arquivo settings.py adicionando-a à lista INSTALLED_APPS.


INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'gestor',
)

Desenvolvimento dos Templates HTML

Utilize templates do Django com Bootstrap para criar a interface. A página de login envia dados via POST e exibe mensagens de status.



{% load staticfiles %}
<html>
<head>
    <meta charset="UTF-8">
    <title>Sistema de Defeitos</title>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'login_custom.css' %}">
</head>
<body>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-4">
                <h1 class="text-center">Acessar Sistema</h1>
                <form method="POST" action="/entrar/">
                    {% csrf_token %}
                    <input type="text" name="usuario" class="form-control" placeholder="Usuário" required>
                    <input type="password" name="senha" class="form-control" placeholder="Senha" required>
                    <button type="submit" class="btn btn-primary btn-block">Entrar</button>
                    <p class="text-danger text-center">{{ mensagem_erro }}</p>
                </form>
            </div>
        </div>
    </div>
    <script src="{% static 'js/jquery.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
</body>
</html>

Crie um layout base para estender outras páginas, garantindo consistência visual.


{% load staticfiles %}
<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <title>Sistema de Defeitos{% block titulo %}{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'dashboard.css' %}">
    {% block estilos %}{% endblock %}
</head>
<body>
    <nav class="navbar navbar-dark bg-dark">
        <div class="container-fluid">
            <a class="navbar-brand" href="/">Sistema de Defeitos</a>
            <div class="navbar-nav">
                {% if usuario.is_authenticated %}
                <a class="nav-link" href="/sair/">Sair ({{ usuario.username }})</a>
                {% endif %}
            </div>
        </div>
    </nav>
    <div class="container-fluid mt-4">
        <div class="row">
            <div class="col-md-3">
                <ul class="nav flex-column">
                    <li class="nav-item"><a class="nav-link" href="/visao-geral/">Visão Geral</a></li>
                    <li class="nav-item"><a class="nav-link" href="/registrar/">Registrar Defeito</a></li>
                    <li class="nav-item"><a class="nav-link" href="/pesquisar/">Pesquisar Defeitos</a></li>
                </ul>
            </div>
            <div class="col-md-9">
                {% block conteudo %}{% endblock %}
            </div>
        </div>
    </div>
    <script src="{% static 'js/jquery.min.js' %}"></script>
    <script src="{% static 'js/bootstrap.min.js' %}"></script>
    {% block scripts %}{% endblock %}
</body>
</html>

As páginas de visão geral, registro, detalhes e pesquisa herdam deste layout. Por exemplo, a página de visão geral exibe uma tabela com defeitos registrados.


{% extends "base/layout.html" %}
{% block conteudo %}
    <h2>Visão Geral dos Defeitos</h2>
    <table class="table table-striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>Título</th>
                <th>Autor</th>
                <th>Data</th>
            </tr>
        </thead>
        <tbody>
            {% for defeito in lista_defeitos %}
            <tr>
                <td><a href="/detalhes/{{ defeito.id }}">{{ defeito.id }}</a></td>
                <td>{{ defeito.titulo }}</td>
                <td>{{ defeito.autor }}</td>
                <td>{{ defeito.data }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
{% endblock %}

Modelos de Dados

Defina um modelo para armazenar informações sobre defeitos. O modelo abaixo inclui campos para título, autor, data e descrição.


from django.db import models
from django.contrib.auth.models import User

class Defeito(models.Model):
    titulo = models.CharField(max_length=120)
    autor = models.CharField(max_length=30)
    data_registro = models.DateField()
    descricao = models.TextField()
    resolvido = models.BooleanField(default=False)

    def __str__(self):
        return self.titulo

Configuração de URLs

Configure as rotas no arquivo urls.py principal para incluir as URLs da aplicação "gestor".


from django.conf.urls import include, url
from django.contrib import admin
from gestor import urls as gestor_urls

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^', include(gestor_urls)),
]

No aplicativo "gestor", defina URLs para login, logout, e operações CRUD.


from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^entrar/$', views.fazer_login),
    url(r'^sair/$', views.fazer_logout),
    url(r'^$', views.pagina_inicial),
    url(r'^visao-geral/$', views.visao_geral),
    url(r'^detalhes/(\d+)/$', views.detalhes_defeito),
    url(r'^registrar/$', views.registrar_defeito),
    url(r'^salvar-defeito/$', views.salvar_defeito),
    url(r'^pesquisar/$', views.pesquisar_defeitos),
]

Implementação das Views

As views lidam com a lógica de autenticação, exibição de páginas e operações no banco de dados. A view de login autentica o usuário e redireciona.


from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Defeito
import datetime

def fazer_login(request):
    if request.user.is_authenticated():
        return redirect('/')
    mensagem = ''
    if request.method == 'POST':
        nome_usuario = request.POST.get('usuario')
        senha = request.POST.get('senha')
        usuario = authenticate(username=nome_usuario, password=senha)
        if usuario is not None:
            login(request, usuario)
            return redirect('/')
        mensagem = 'Credenciais inválidas. Tente novamente.'
    return render(request, 'login/entrar.html', {'mensagem_erro': mensagem})

def fazer_logout(request):
    logout(request)
    return redirect('/entrar/')

@login_required
def pagina_inicial(request):
    return render(request, 'principal/home.html', {'usuario': request.user})

@login_required
def visao_geral(request):
    defeitos = Defeito.objects.all().order_by('-id')
    return render(request, 'principal/visao_geral.html', {'lista_defeitos': defeitos, 'usuario': request.user})

@login_required
def detalhes_defeito(request, defeito_id):
    defeito = Defeito.objects.get(id=defeito_id)
    return render(request, 'principal/detalhes.html', {'defeito': defeito, 'usuario': request.user})

@login_required
def registrar_defeito(request):
    return render(request, 'principal/registrar.html', {'usuario': request.user})

@login_required
@csrf_exempt
def salvar_defeito(request):
    if request.method == 'POST':
        titulo = request.POST.get('titulo')
        descricao = request.POST.get('descricao')
        data_atual = datetime.date.today().isoformat()
        try:
            Defeito.objects.create(titulo=titulo, autor=request.user.username, data_registro=data_atual, descricao=descricao)
            return redirect('/visao-geral/')
        except Exception as e:
            return HttpResponse(f"Erro ao salvar: {str(e)}")
    return HttpResponse("Método não permitido.", status=405)

@login_required
@csrf_exempt
def pesquisar_defeitos(request):
    if request.method == 'POST':
        filtros = {}
        autor = request.POST.get('autor', '')
        data_inicio = request.POST.get('data_inicio', '')
        data_fim = request.POST.get('data_fim', '')
        status = request.POST.get('status', '')
        
        if autor:
            filtros['autor__icontains'] = autor
        if data_inicio:
            filtros['data_registro__gte'] = data_inicio
        if data_fim:
            filtros['data_registro__lte'] = data_fim
        if status == 'resolvido':
            filtros['resolvido'] = True
        elif status == 'pendente':
            filtros['resolvido'] = False
        
        resultados = Defeito.objects.filter(**filtros).order_by('-id')
        html_saida = ''
        for item in resultados:
            html_saida += f"<tr><td><a href='/detalhes/{item.id}'>{item.id}</a></td><td>{item.titulo}</td><td>{item.autor}</td><td>{item.data_registro}</td></tr>"
        return HttpResponse(html_saida)
    return render(request, 'principal/pesquisar.html', {'usuario': request.user})

Funções Auxiliares em JavaScript

Inclua scripts personalizados para manipulação de eventos e validações no cliente. O código abaixo gerencia requisições AJAX e validação de datas.


function enviarRequisicao(url, dados, callback) {
    $.ajax({
        type: 'POST',
        url: url,
        data: dados,
        cache: false,
        async: true,
        success: callback
    });
}

function validarIntervaloData(dataInicial, dataFinal) {
    var inicio = new Date(dataInicial);
    var fim = new Date(dataFinal);
    return inicio.getTime() <= fim.getTime();
}

Execute o servidor com python manage.py runserver para testar a aplicação. Acesse via navegador para verificar todas as funcionalidades.

Tags: Django Python MySQL bootstrap Django-templates

Publicado em 6-17 17:47