Add Flask Postgres CRUD demo
This commit is contained in:
parent
e0859a05c6
commit
93a0acf36a
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1,3 @@
|
||||
site/templates/
|
||||
site/static/
|
||||
venv/
|
||||
@ -1,2 +1,4 @@
|
||||
# Baulder-s-Gate-test
|
||||
A test to find out who you are from the game Baldur's Gate.
|
||||
# Flask + Postgres Demo
|
||||
|
||||
Простое CRUD-приложение на Flask, которое пишет и читает из таблицы `nubes_test_table`.
|
||||
Если поле ввода пустое, вставляется запись "Это Flask сделал".
|
||||
@ -1,2 +1,3 @@
|
||||
Flask==2.0.1
|
||||
Werkzeug==2.3.7
|
||||
Werkzeug==2.3.7
|
||||
psycopg2-binary==2.9.9
|
||||
216
site/app.py
216
site/app.py
@ -1,121 +1,117 @@
|
||||
from flask import Flask, render_template, request
|
||||
import os
|
||||
|
||||
class BaldursGateQuizApp:
|
||||
def __init__(self):
|
||||
self.app = Flask(__name__, template_folder="templates", static_folder="static")
|
||||
self.add_routes()
|
||||
import psycopg2
|
||||
from flask import Flask, redirect, render_template_string, request
|
||||
|
||||
def add_routes(self):
|
||||
self.app.add_url_rule('/', 'index', self.index)
|
||||
self.app.add_url_rule('/result', 'result', self.result, methods=["POST"])
|
||||
self.app.add_url_rule('/tests', 'tests', self.tests)
|
||||
self.app.add_url_rule('/about', 'about', self.about)
|
||||
app = Flask(__name__)
|
||||
|
||||
def index(self):
|
||||
return render_template("index.html")
|
||||
|
||||
def tests(self):
|
||||
return render_template("tests.html")
|
||||
def get_conn():
|
||||
db_url = os.getenv("DATABASE_URL")
|
||||
if db_url:
|
||||
return psycopg2.connect(db_url)
|
||||
return psycopg2.connect(
|
||||
host=os.getenv("PGHOST"),
|
||||
port=os.getenv("PGPORT", "5432"),
|
||||
user=os.getenv("PGUSER"),
|
||||
password=os.getenv("PGPASSWORD"),
|
||||
dbname=os.getenv("PGDATABASE", "postgres"),
|
||||
sslmode=os.getenv("PGSSLMODE", "require"),
|
||||
)
|
||||
|
||||
def result(self):
|
||||
answers = request.form
|
||||
character = self.determine_character(answers)
|
||||
return render_template("result.html", character=character)
|
||||
|
||||
def about(self):
|
||||
return render_template("about.html")
|
||||
def ensure_table():
|
||||
with get_conn() as conn, conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS nubes_test_table (
|
||||
id SERIAL PRIMARY KEY,
|
||||
test_data TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
"""
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def determine_character(answers):
|
||||
traits = {
|
||||
"brave": "Минск",
|
||||
"wise": "Гейл",
|
||||
"kind": "Карлах",
|
||||
"cunning": "Астарион",
|
||||
"strict": "Лаэзель",
|
||||
"dark": "Шэдоухарт"
|
||||
}
|
||||
roles = {
|
||||
"leader": "Минск",
|
||||
"healer": "Хальсин",
|
||||
"fighter": "Карлах",
|
||||
"rogue": "Астарион",
|
||||
"mage": "Гейл"
|
||||
}
|
||||
goals = {
|
||||
"glory": "Минск",
|
||||
"knowledge": "Гейл",
|
||||
"protect": "Шэдоухарт",
|
||||
"power": "Лаэзель"
|
||||
}
|
||||
rules = {
|
||||
"strict": "Лаэзель",
|
||||
"flexible": "Гейл",
|
||||
"pragmatic": "Астарион",
|
||||
"chaotic": "Шэдоухарт"
|
||||
}
|
||||
weapons = {
|
||||
"sword": "Минск",
|
||||
"staff": "Гейл",
|
||||
"dagger": "Астарион",
|
||||
"mace": "Карлах",
|
||||
"bow": "Лаэзель"
|
||||
}
|
||||
places = {
|
||||
"tavern": "Карлах",
|
||||
"library": "Гейл",
|
||||
"wilderness": "Хальсин",
|
||||
"castle": "Лаэзель",
|
||||
"dark_alley": "Шэдоухарт"
|
||||
}
|
||||
mood_fix = {
|
||||
"training": "Лаэзель",
|
||||
"reading": "Гейл",
|
||||
"adventure": "Минск",
|
||||
"meditation": "Шэдоухарт",
|
||||
"drinking": "Карлах"
|
||||
}
|
||||
colors = {
|
||||
"red": "Карлах",
|
||||
"blue": "Гейл",
|
||||
"green": "Хальсин",
|
||||
"black": "Шэдоухарт",
|
||||
"gold": "Лаэзель"
|
||||
}
|
||||
|
||||
choices = [
|
||||
traits.get(answers.get("question1")),
|
||||
roles.get(answers.get("question2")),
|
||||
goals.get(answers.get("question3")),
|
||||
rules.get(answers.get("question4")),
|
||||
weapons.get(answers.get("question5")),
|
||||
places.get(answers.get("question6")),
|
||||
mood_fix.get(answers.get("question7")),
|
||||
colors.get(answers.get("question8"))
|
||||
]
|
||||
|
||||
choices = [choice for choice in choices if choice is not None]
|
||||
|
||||
if not choices:
|
||||
return {"name": "Неизвестно", "image": "unknown.jpg", "description": "Не удалось определить персонажа."}
|
||||
|
||||
most_common = max(set(choices), key=choices.count)
|
||||
|
||||
characters_info = {
|
||||
"Минск": {"name": "Минск", "image": "minsk.jpg", "description": "Герой, идущий напролом с верным хомяком Бу"},
|
||||
"Гейл": {"name": "Гейл", "image": "gale.jpg", "description": "Могущественный маг, жаждущий знаний и силы"},
|
||||
"Карлах": {"name": "Карлах", "image": "karlach.jpg", "description": "Добрая, но грозная воительница"},
|
||||
"Астарион": {"name": "Астарион", "image": "astarion.jpeg", "description": "Хитрый вампир, любящий свободу"},
|
||||
"Лаэзель": {"name": "Лаэзель", "image": "laezel.jpg", "description": "Жесткая и бескомпромиссная гитянка-воительница"},
|
||||
"Шэдоухарт": {"name": "Шэдоухарт", "image": "shadowheart.jpg", "description": "Таинственная жрица с темным прошлым"},
|
||||
"Хальсин": {"name": "Хальсин", "image": "halsin.jpg", "description": "Мудрый друид, защитник природы."}
|
||||
}
|
||||
PAGE = """
|
||||
<!doctype html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Flask + Postgres Demo</title>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Flask + Postgres Demo</h3>
|
||||
{% if error %}<p style="color:red">{{ error }}</p>{% endif %}
|
||||
<form method="post">
|
||||
<input type="text" name="txt_content" placeholder="Новое сообщение...">
|
||||
<button type="submit">Добавить</button>
|
||||
</form>
|
||||
<table border="1" cellpadding="6" cellspacing="0">
|
||||
<tr><th>ID</th><th>Содержимое</th><th>Действия</th></tr>
|
||||
{% for row in rows %}
|
||||
<tr>
|
||||
<td>{{ row[0] }}</td>
|
||||
<td>
|
||||
<form method="post" action="/update">
|
||||
<input type="hidden" name="id" value="{{ row[0] }}">
|
||||
<input type="text" name="txt_content" value="{{ row[1] }}">
|
||||
<button type="submit">💾</button>
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<form method="post" action="/delete" onsubmit="return confirm('Удалить?')">
|
||||
<input type="hidden" name="id" value="{{ row[0] }}">
|
||||
<button type="submit">🗑</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
@app.route("/", methods=["GET", "POST"])
|
||||
def index():
|
||||
ensure_table()
|
||||
error = None
|
||||
if request.method == "POST":
|
||||
content = request.form.get("txt_content") or "Это Flask сделал"
|
||||
try:
|
||||
with get_conn() as conn, conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"INSERT INTO nubes_test_table (test_data) VALUES (%s)",
|
||||
(content,),
|
||||
)
|
||||
return redirect("/")
|
||||
except Exception as exc:
|
||||
error = str(exc)
|
||||
with get_conn() as conn, conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"SELECT id, test_data FROM nubes_test_table ORDER BY id DESC LIMIT 20"
|
||||
)
|
||||
rows = cur.fetchall()
|
||||
return render_template_string(PAGE, rows=rows, error=error)
|
||||
|
||||
|
||||
@app.post("/update")
|
||||
def update():
|
||||
with get_conn() as conn, conn.cursor() as cur:
|
||||
cur.execute(
|
||||
"UPDATE nubes_test_table SET test_data=%s WHERE id=%s",
|
||||
(request.form.get("txt_content"), request.form.get("id")),
|
||||
)
|
||||
return redirect("/")
|
||||
|
||||
|
||||
@app.post("/delete")
|
||||
def delete():
|
||||
with get_conn() as conn, conn.cursor() as cur:
|
||||
cur.execute("DELETE FROM nubes_test_table WHERE id=%s", (request.form.get("id"),))
|
||||
return redirect("/")
|
||||
|
||||
return characters_info.get(most_common, {"name": "Неизвестно", "image": "unknown.jpg", "description": "Не удалось определить персонажа."})
|
||||
|
||||
def run(self):
|
||||
self.app.run(debug=True, host="0.0.0.0", port=5000)
|
||||
|
||||
if __name__ == "__main__":
|
||||
app_instance = BaldursGateQuizApp()
|
||||
app_instance.run()
|
||||
app.run(debug=True, host="0.0.0.0", port=5000)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user