LINUX.ORG.RU

Сообщения demonworm

 

flask-wtforms как работают фильтры полей?

В документации wtforms внятно не описано, как их применять, нет практичных примеров. Вот, допустим, есть класс:

class AddForm(FlaskForm):
    name = StringField('Название', filters=[name_to_upper(name)], validators=[DataRequired()])
    
    def name_to_upper(name):
        return name.upper()

Как мне name_to_upper применить внутри класса к name после его ввода (судя по докам и до валидации)?

Если пробовать в таком виде, как у меня, ругается

name = StringField('Название', filters=[name_to_upper(name)], validators=[DataRequired()])                                                                

                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
NameError: name 'name' is not defined

Какую подстановку использовать?

 ,

demonworm
()

sqlite3 left self-join, только наоборот

MWE

#!/usr/bin/env python3

import sqlite3

db = 'test.db'
conn = sqlite3.connect(db)
cur = conn.cursor()

# Create schema.
cur.execute('''CREATE TABLE IF NOT EXISTS objects (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
content TEXT NOT NULL,
parentid INTEGER NOT NULL,
UNIQUE(name)
)''')
conn.commit()

# Fill db.
data = [('obj1', 'hello', 0,),
        ('obj2', 'hi', 1,),
        ('obj3', 'aloha', 0)]
cur.executemany('INSERT OR IGNORE INTO objects (name, content, parentid) VALUES (?, ?, ?)',
                (data))
conn.commit()

# Show objects table content as it is.
db_data = cur.execute('SELECT * FROM objects').fetchall()
print(db_data)

# Left self-join.
db_data2 = cur.execute('''SELECT o.id, o.name, od.name AS parentname
FROM objects AS o
LEFT JOIN objects AS od ON o.id = od.parentid''').fetchall()
print(db_data2)

Вывод

./test-sqlite-db.py 
[(1, 'obj1', 'hello', 0), (2, 'obj2', 'hi', 1), (3, 'obj3', 'aloha', 0)]
[(1, 'obj1', 'obj2'), (2, 'obj2', None), (3, 'obj3', None)]

Получается, что parentid совсем не parent, а child. Как заджоинить (универсально, чтобы остальные элементы выводились так же без доп. проверок и лишних итераций) так, чтобы вместо

[(1, 'obj1', >>>'obj2'<<<), (2, 'obj2', >>>None<<<), (3, 'obj3', None)]

стало

[(1, 'obj1',>>>None<<<), (2, 'obj2', >>>'obj1'<<<), (3, 'obj3', None)]

Очень желательно, чтобы все оставалось в рамках одной таблицы. Показывать нужно обязательно все записи, даже там, где нет parentid.

 , ,

demonworm
()

Помощь с Flask: отправить переменную с кнопки, но так, чтобы было не post

Суть такая.

Страница с кнопкой:

        <form action="{{ url_for('add_journal_record') }}" method="post">
          <input type="hidden" name="docid" value="{{ doc['id'] }}">
          <input type="hidden" name="docname" value="{{ doc['docname'] }}">
          <input type="submit" value="Send">
        </form>

Маршрут:

@app.route('/add_journal_record', methods=('GET', 'POST'))
def add_journal_record():
    docid = request.form['docid']
    docname = request.form['docname']
    conn = get_db_connection()
    people = conn.execute('SELECT p.id, p.personname FROM people AS p;').fetchall()
    statuses = conn.execute('SELECT s.id, s.statusname FROM statuses AS s;').fetchall()
    if request.method == 'POST':
        journaldate = request.form['journaldate']
        personid = request.form['person']
        statusid = request.form['status']
        comment = request.form['comment']
        conn.execute('INSERT INTO journal (docid, personid, statusid, journaldate, comment) VALUES (?, ?, ?, ?, ?)',
                     (docid, journaldate, personid, statusid, comment))
        conn.commit()
        conn.close()
        return redirect(url_for('index'))
    return render_template('add_journal_record.html', people=people, statuses=statuses, docname=docname)

Из add_journal_record.html:

  <input type="date"
         name="journaldate"
         min="2018-01-01"
         required
         value={{ request.form['journaldate'] }}>

Если делать так, то ругается на werkzeug.exceptions.BadRequestKeyError / 400 Bad Request in Flask, что ключи не найдены. Как я понял, дело в том, что из-за передачи из первого куска doc['id'] и doc['docname'] через post, маршрут сразу считает, что обрабатывает post, а значит все переменные, которые я присваиваю после if request.method == "POST": не обнаруживаются (их еще не заполнили). Жанглирование с get не сработают, т.к. тогда doc['*'] не передастся.

Вопрос: как правильно передать по кнопке переменную, но чтобы это не считалось post? Правильно ли я вообще пытаюсь это сделать или есть пути правильнее/проще? Нуб во flask и python, да и в программировании в целом. Пилю для себя.

 , , ,

demonworm
()

HyperSQL запрос на получение последнего статуса при условии

Есть таблица вида

ID Obj      Stat   Stat_date
1  Объект1  1      01.01.2023
2  Объект2  2      02.03.2023
3  Объект1  2      22.08.2023
4  Объект3  2      15.09.2023
5  Объект4  1      01.02.2023
6  Объект3  3      21.09.2023

Я все представляю упрощенно, чтобы не вмешивать лишнее. На самом деле в базе 5 таблиц, один связаны друг с другом и т. п.

Как видно, это вроде истории изменения статуса объектов. В этой таблице у объекта может быть много статусов. Я пытаюсь сформировать запрос, который выдаст мне

все объекты, чей *последний* за последние 300 дней равен 2

Если решать это в лоб, как попробовал я, получается результат, который мне не нужен:

SELECT ID, Obj, Stat, Stat_date
WHERE DATEDIFF('day', Stat_date, CURRENT_DATE) <= 300 AND Stat = 2

При таком запросе в результат попадут Объект1, Объект2, Объект3, хотя Объект3 последним статусом имеет 3, а не 2. Получается, последовательность фильтров это не последовательность, а одновременно применение. Подозреваю, что мне нужны два отдельных SELECT или какой-то комплексный фильтр, чтобы применять внутри него фильтры последовательно (каждый последующий фильтр обрабатывает результаты предыдущего), но не понимаю, как это сделать.

P.S. Не хватает тегов hsqldb/hypersql.

Перемещено hobbit из general

 ,

demonworm
()

RSS подписка на новые темы