Flask для школьниковСправочник
SilverTests.ruFlask + SQLite + JS
Справочник функций
Flask + SQLite + Jinja2 + JavaScript
1Flask: маршруты и ответы
| Функция |
Что делает |
Пример |
@app.route(url) |
Связывает URL с функцией. По умолчанию только GET. |
@app.route('/habits') |
@app.route(url, methods=[...]) |
Разрешить указанные HTTP-методы. |
@app.route('/add', methods=['POST']) |
render_template(file, **vars) |
Загрузить HTML из templates/, подставить переменные. |
render_template('habits.html', habits=rows) |
redirect(url) |
Перенаправить браузер (HTTP 302). После POST — чтобы F5 не отправил форму повторно. |
redirect('/habits') |
jsonify(data) |
Словарь/список → JSON-ответ + заголовок Content-Type: application/json. |
jsonify({"ok": True}) |
url_for(func_name) |
URL по имени функции. Безопаснее строки. |
url_for('habits') → '/habits' |
abort(code) |
Прервать обработку, вернуть HTTP-ошибку. |
abort(404) |
2Flask: данные от пользователя
| Объект |
Откуда |
Пример |
request.form['key'] |
HTML-форма (POST). Ключ = атрибут name у input. |
request.form['habit_name'] |
request.json |
JSON от JavaScript (fetch + Content-Type: application/json). |
data = request.json |
request.args.get('key') |
Параметры из URL после ?. |
request.args.get('q', '') |
request.method |
Метод запроса: 'GET' или 'POST'. |
if request.method == 'POST': |
request.files['key'] |
Загруженный файл из формы. |
file = request.files['photo'] |
Когда какой: HTML-форма → request.form. JavaScript fetch → request.json. Ссылка ?q=бег → request.args.
3Flask: динамические маршруты
| Синтаксис |
Тип |
Пример |
<name> |
Строка |
/user/Аня → name="Аня" |
<int:id> |
Целое число |
/toggle/3 → id=3 |
<float:price> |
Дробное |
/item/9.99 → price=9.99 |
<path:p> |
Путь (с /) |
/files/a/b.pdf → p="a/b.pdf" |
4Jinja2: шаблоны
| Синтаксис |
Что делает |
Пример |
{{ var }} |
Вывести значение. |
{{ habit['name'] }} |
{% for x in list %}...{% endfor %} |
Цикл. |
{% for h in habits %}<li>{{ h['name'] }}</li>{% endfor %} |
{% if cond %}...{% endif %} |
Условие. |
{% if habit['done'] %}Готово{% endif %} |
{% extends 'base.html' %} |
Наследование шаблона. |
В начале дочернего файла. |
{% block name %}...{% endblock %} |
Переопределяемый блок. |
{% block content %}...{% endblock %} |
{{ var | filter }} |
Фильтр. |
{{ items | length }}, {{ name | upper }} |
{{ url_for('func') }} |
URL по имени функции. |
<a href="{{ url_for('habits') }}"> |
{{ }} — вывод значения. {% %} — управляющие конструкции (for, if, block). Не путай!
5SQLite: подключение
| Функция |
Что делает |
Пример |
sqlite3.connect(path) |
Открыть файл БД (создаёт если нет). |
conn = sqlite3.connect('habits.db') |
conn.row_factory = sqlite3.Row |
Доступ по имени: row['name']. |
Ставить сразу после connect. |
conn.execute(sql, params) |
Выполнить SQL. Параметры через ?. |
conn.execute('...WHERE id=?', (3,)) |
conn.commit() |
Сохранить на диск. Обязателен после INSERT/UPDATE/DELETE. |
conn.commit() |
conn.close() |
Закрыть соединение. Обязателен всегда. |
conn.close() |
Паттерн
# Чтение
conn = get_db()
rows = conn.execute('SELECT * FROM habits').fetchall()
conn.close()
# Запись (commit обязателен!)
conn = get_db()
conn.execute('INSERT INTO habits (name) VALUES (?)', (name,))
conn.commit()
conn.close()
6SQLite: результаты
| Метод |
Возвращает |
Когда |
.fetchall() |
Список всех строк. |
Все привычки, все пользователи. |
.fetchone() |
Одна строка или None. |
Привычка по id. |
.fetchmany(n) |
Первые n строк. |
Порция результатов. |
.lastrowid |
id последней вставки. |
После INSERT: узнать новый id. |
7SQL: команды
| Команда |
Пример |
CREATE TABLE |
CREATE TABLE IF NOT EXISTS habits (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, done INTEGER DEFAULT 0) |
INSERT INTO |
INSERT INTO habits (name) VALUES (?) |
SELECT |
SELECT * FROM habits WHERE done = 1 |
UPDATE |
UPDATE habits SET done = 1 WHERE id = 3 |
DELETE FROM |
DELETE FROM habits WHERE id = 5 |
ORDER BY |
SELECT * FROM habits ORDER BY name ASC |
LIMIT |
SELECT * FROM habits LIMIT 10 |
COUNT(*) |
SELECT COUNT(*) FROM habits WHERE done = 1 |
LIKE |
WHERE name LIKE '%бег%' |
ALTER TABLE |
ALTER TABLE habits ADD COLUMN created_at TEXT |
datetime('now') |
INSERT INTO ... VALUES (?, datetime('now')) |
Безопасность: данные от пользователя ВСЕГДА через ?, НИКОГДА через f-строку. Запятая в кортеже: (name,) — кортеж, (name) — скобки.
8JavaScript: fetch и DOM
| Функция |
Что делает |
Пример |
fetch(url) |
GET-запрос. |
fetch('/api/habits') |
fetch(url, {method:'POST',...}) |
POST с телом. |
см. шаблон ниже |
.then(fn) |
«Когда готово — вызови.» |
.then(r => r.json()) |
JSON.stringify(obj) |
JS-объект → JSON-строка. |
body: JSON.stringify({name:'Бег'}) |
setInterval(fn, ms) |
Повторять каждые ms мс. |
setInterval(loadState, 1500) |
document.getElementById(id) |
Найти элемент по id. |
document.getElementById('list') |
el.innerHTML |
HTML внутрь элемента. |
el.innerHTML = '<li>Бег</li>' |
document.createElement(tag) |
Создать элемент. |
document.createElement('li') |
el.appendChild(child) |
Вставить внутрь. |
ul.appendChild(li) |
el.addEventListener(ev, fn) |
Обработчик события. |
btn.addEventListener('click', fn) |
Шаблон: fetch POST с JSON
fetch('/api/add', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Бег' })
}).then(r => r.json()).then(data => { /* ... */ });
Шаблон: polling
function loadState() {
fetch('/api/state').then(r => r.json()).then(data => { /* обновить DOM */ });
}
loadState();
setInterval(loadState, 1500); // БЕЗ скобок!
9Типичные ошибки
| Ошибка |
Симптом |
Исправление |
Забыл commit() |
Данные пропадают после перезапуска. |
conn.commit() после INSERT/UPDATE/DELETE. |
Забыл close() |
database is locked. |
conn.close() в конце маршрута. |
(name) вместо (name,) |
Incorrect number of bindings. |
Запятая: (name,). |
| f-строка в SQL |
SQL-инъекция. |
Использовать ?. |
no such table |
Таблица не создана. |
Вызвать init_db(). |
405 Method Not Allowed |
Неправильный метод. |
methods=['POST'] в route. |
setInterval(fn(), ms) |
Polling не работает. |
Убрать скобки: fn. |
| Пустой ответ API |
Нет return. |
return jsonify(...). |