Commit 2d5f1163 by 2024105070067

Primeiro commit do CRUD

parents
import os
from flask import Flask, render_template, request, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# Configurações usando boas práticas
basedir = os.path.abspath(os.path.dirname(__file__))
app.config.update(
SQLALCHEMY_DATABASE_URI='sqlite:///' + os.path.join(basedir, 'database.db'),
SQLALCHEMY_TRACK_MODIFICATIONS=False,
SECRET_KEY=os.environ.get('SECRET_KEY', 'dev-key-muito-segura') # Para usar flash messages
)
db = SQLAlchemy(app)
# Modelo - Melhorei os tipos de dados e restrições
class Pessoa(db.Model):
id = db.Column(db.Integer, primary_key=True)
nome = db.Column(db.String(100), nullable=False)
sexo = db.Column(db.String(20))
data_nascimento = db.Column(db.String(20)) # Para usar Date real, exigiria conversão de string
cidade = db.Column(db.String(100))
telefone = db.Column(db.String(20), nullable=False)
def __repr__(self):
return f'<Pessoa {self.nome}>'
@app.route('/')
def index():
# Ordenar por nome facilita a leitura na tabela
pessoas = Pessoa.query.order_by(Pessoa.nome).all()
return render_template('index.html', pessoas=pessoas)
@app.route('/cadastro', methods=['GET', 'POST'])
def cadastro():
if request.method == 'POST':
try:
# Captura de dados de forma mais limpa
dados = request.form
nova_pessoa = Pessoa(
nome=dados.get('nome'),
sexo=dados.get('sexo'),
data_nascimento=dados.get('data_nascimento'),
cidade=dados.get('cidade'),
telefone=dados.get('telefone')
)
db.session.add(nova_pessoa)
db.session.commit()
return redirect(url_for('index'))
except Exception as e:
db.session.rollback()
print(f"Erro ao salvar: {e}")
return "Ocorreu um erro ao salvar os dados.", 500
return render_template('cadastro.html')
if __name__ == '__main__':
with app.app_context():
db.create_all()
app.run(debug=True)
\ No newline at end of file
File added
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cadastro</title>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
background: #f0f2f5;
display: grid;
place-items: center;
min-height: 100vh;
margin: 0;
}
form {
background: #fff;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0,0,0,0.1);
width: 100%;
max-width: 360px;
display: flex;
flex-direction: column;
gap: 1rem;
}
h2 { margin: 0 0 0.5rem; font-size: 1.4rem; text-align: center; }
label { font-size: 0.9rem; font-weight: 500; margin-bottom: -0.6rem; color: #555; }
input, select {
padding: 10px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 1rem;
}
input:focus { outline: 2px solid #007bff; border-color: transparent; }
button {
background: #007bff;
color: #fff;
border: none;
padding: 12px;
border-radius: 6px;
font-weight: 600;
cursor: pointer;
transition: 0.2s;
}
button:hover { background: #0056b3; }
a { text-align: center; font-size: 0.85rem; color: #666; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<form method="POST">
<h2>Nova Pessoa</h2>
<label>Nome</label>
<input type="text" name="nome" required>
<label>Sexo</label>
<select name="sexo">
<option value="M">Masculino</option>
<option value="F">Feminino</option>
</select>
<label>Nascimento</label>
<input type="date" name="data_nascimento" required>
<label>Cidade</label>
<input type="text" name="cidade" required>
<label>Telefone</label>
<input type="tel" name="telefone" placeholder="(00) 00000-0000" required>
<button type="submit">Salvar Cadastro</button>
<a href="/">Voltar para a lista</a>
</form>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lista de Pessoas</title>
<style>
body {
font-family: system-ui, -apple-system, sans-serif;
background-color: #f8fafc;
color: #334155;
margin: 0;
padding: 2rem;
display: flex;
justify-content: center;
}
.container {
width: 100%;
max-width: 1000px;
background: white;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
h1 { font-size: 1.5rem; margin: 0; color: #1e293b; }
.btn-new {
background-color: #2563eb;
color: white;
text-decoration: none;
padding: 10px 20px;
border-radius: 6px;
font-weight: 600;
font-size: 0.9rem;
transition: background 0.2s;
}
.btn-new:hover { background-color: #1d4ed8; }
/* Estilização da Tabela */
.table-container { overflow-x: auto; } /* Essencial para celular */
table {
width: 100%;
border-collapse: collapse;
text-align: left;
}
th {
background-color: #f1f5f9;
padding: 12px 15px;
font-size: 0.85rem;
text-transform: uppercase;
letter-spacing: 0.05em;
color: #64748b;
border-bottom: 2px solid #e2e8f0;
}
td {
padding: 12px 15px;
border-bottom: 1px solid #f1f5f9;
font-size: 0.95rem;
}
tr:hover { background-color: #f8fafc; }
/* Estilo para quando não houver dados */
.empty-msg {
text-align: center;
padding: 2rem;
color: #94a3b8;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>Pessoas Cadastradas</h1>
<a href="/cadastro" class="btn-new">+ Novo Cadastro</a>
</div>
<div class="table-container">
<table>
<thead>
<tr>
<th>Nome</th>
<th>Sexo</th>
<th>Nascimento</th>
<th>Cidade</th>
<th>Telefone</th>
</tr>
</thead>
<tbody>
{% for p in pessoas %}
<tr>
<td><strong>{{ p.nome }}</strong></td>
<td>{{ p.sexo }}</td>
<td>{{ p.data_nascimento }}</td>
<td>{{ p.cidade }}</td>
<td>{{ p.telefone }}</td>
</tr>
{% else %}
<tr>
<td colspan="5" class="empty-msg">Nenhuma pessoa cadastrada ainda.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment