【问题标题】:How to get value from database to create dynamic names for inputs in looped form?如何从数据库中获取值以为循环形式的输入创建动态名称?
【发布时间】:2021-02-26 10:43:59
【问题描述】:

我在一个使用 HTML、Python、SQL 和 Flask 的网站上工作,我遇到了一个问题,因为我想在一个部分中使用数据库中名为抽认卡的表中的数据进行测验,其中包括这些列:

id_flashcard (INT) |语言(文本) |字(文本) |定义(文本) | user_id (INT)


编辑:数据库结构users.db

[表格] 抽认卡

id_flashcard (INT) | language (TEXT) | word (TEXT) | definition (TEXT) | user_id (INT)

    1          |     Italian     |  il gatto   |     the cat       |      2

[表格]语言

language (TEXT)    | flashcards (INT)|  quiz (INT) |   average (REAL)  | user_id (INT)

  Italian      |        1        |       0     |        0.0        |      2

[表格]测验

user_id (INT) | language (TEXT) | n_flashcards (INT)| correct_answers (INT) | avg_quiz (REAL) |  date (DATETIME)

[表格]用户

id (INT)      |  username (TEXT) | hash (TEXT)

为了进行这个测验,我循环访问了一个表格,该表格包含测验所需的所有卡片(在上一页中,用户可以选择语言),显示定义并让用户写下正确的“单词”。 现在,我的第一个问题是我需要能够为每个输入提供某种标识符,以便在提交后检索答案。

这是我多次尝试后得到的:

HTML 表单:

<form action="/quiztab" method="post">
   {% for card in db_user %}
   <div class="form-group row roundform">
       <label for="staticEmail" class="col-sm-5 col-form-label" name="def_quiz[{{ card['id_flashcard'] }}]">{{ card["definition"] }}</label>
       <div class="col-sm-10">
           <input autocomplete="off" class="form-control roundform" type="text" name="answer[{{ card['id_flashcard'] }}]" placeholder="Write here the correct translation!">
       </div>
   </div>
   {% endfor %}
   <button class="roundbutton mt-5" type="submit">Give me the results!</button>
</form>

应用:

def quiztab():
    quiz_language = session.get('quiz_language', None)
    user_id = session["user_id"]
    overview_languages = db.execute("SELECT * FROM languages WHERE user_id = :user_id", user_id = user_id)
    db_user = db.execute("SELECT * FROM flashcards WHERE user_id = :user_id AND language = :quiz_language", user_id = user_id, quiz_language = quiz_language)
    cards = db.execute("SELECT word, definition FROM flashcards WHERE user_id = :user_id AND language = :quiz_language", user_id = user_id, quiz_language = quiz_language)
    n_cards = db.execute("SELECT COUNT(*) as count FROM flashcards WHERE user_id = :user_id AND language = :quiz_language", user_id = user_id, quiz_language = quiz_language)[0]["count"]
    id_flashcards = db.execute("SELECT id_flashcard FROM flashcards WHERE user_id = :user_id AND language = :quiz_language", user_id = user_id, quiz_language = quiz_language)

    answer = []
    def_quiz = []

    if request.method == "POST":
       answer.append(request.form.get("answer[{{ card['id_flashcard'] }}]"))
       def_quiz.append(request.form.get("def_quiz[{{ card['id_flashcard'] }}]"))

       results = 0

       for x in answer:
          for y in def_quiz:
             correct_word = db.execute("SELECT word FROM flashcards WHERE user_id = :user_id AND language = :quiz_language AND definition = :definition", user_id = user_id, quiz_language = quiz_language, definition = def_quiz)
             if correct_word == answer:
                results = results + 1
             else:
                results = results

       add_quiz = db.execute("UPDATE languages SET quiz = quiz + 1 WHERE user_id = :user_id AND language = :quiz_language", user_id = user_id, quiz_language = quiz_language)
       avg = ((results / n_cards) * 100)
       update_quizzes = db.execute("INSERT INTO quizzes (user_id, language, n_flashcards, correct_answers, avg_quiz) VALUES (:user_id, :language, :n_flashcards, :correct_answers, :avg)", user_id = user_id, language = quiz_language, n_flashcards = n_cards, correct_answers = results, avg = avg)

       answer = []
       def_quiz = []
       return redirect("/quiz")

    else:
       return render_template("quiztab.html", db_user = db_user, id_flashcards = id_flashcards)

不幸的是,我仍然无法获得输入并基本上检查它们是否正确,而且由于我还是初学者,我发现自己不知道如何解决和解决这个问题。

非常感谢任何帮助:)

【问题讨论】:

  • 您能否在您的问题中添加您的数据库模型以及语言和抽认卡表中的记录示例(如果可能)?
  • 到目前为止实际工作的是什么?你能渲染测验表吗?你能提交什么吗?
  • 使用 GET quiztab 渲染,一切似乎都正常,但是一旦我提交表单,方法就会更改为 POST,即使我被正确重定向回 /quiz 我也无法获得表单的输入(应用程序中的“answer”和“def_answer”)。我认为有问题的部分是当我尝试从表单中获取所有输入时,因此在 HTML 中我尝试获取一种标识的方式和在应用程序中的“request.form.get”。

标签: python html forms flask input


【解决方案1】:

由于我无法重现您的所有代码,因此我在这里提供了一个小示例,您可以从中汲取灵感

app.py:

from flask import Flask, render_template, request

app = Flask(__name__)


@app.route("/home", methods=['GET', 'POST'])
def home():
    # Suppose that after the sql request the data is in this form
    quiz = [{'id': 1, 'def_quiz': 'il gato', 'answer': 'the cat'},
            {'id': 2, 'def_quiz': 'il cane', 'answer': 'the dog'}]

    if request.method == "POST":

        # I convert the form's data to dictionary
        data = request.form.to_dict()

        # this gives me a dictionary of the form {'def_quiz_id': 'answer_typed'}
        # {'1': 'the cat', '2': 'the dog'}
        print(data)
        result = 0

        for def_quiz, answer in data.items():
            print(def_quiz, answer)
            # replace this line with your sql request
            recorded_answer = [q for q in quiz if q['id'] == int(def_quiz)][0]['answer']
            print("the answer recorded", recorded_answer)
            if recorded_answer == answer:
                result += 1
        print("result: ", result)

        # the rest of your code here...
        
    return render_template('home.html', quiz=quiz)


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000, debug=True)

模板/home.html:

<!DOCTYPE html>
<form action="/home" method="post">
   {% for q in quiz %}
   <div class="form-group">
       <label>{{ q["def_quiz"] }}</label>
       <div>
           <input type="text" name="{{ q['id'] }}" placeholder="Write here the correct translation!">
       </div>
   </div>
   {% endfor %}
   <button type="submit">Give me the results!</button>
</form>

【讨论】:

  • 谢谢托宾,我会试试这个!我只是想知道,对于 app.py 中的“测验”,您的意思是我的变量“db_user”?
  • 这部分还是有问题的:对于定义,在data.items()中回答:recorded_answer = [q for q in db_user if q['id_flashcard'] == int(definition)] [0]['answer'] print("已记录的答案",recorded_answer) ifrecorded_answer == answer: result += 1 KeyError: 'answer'
  • 你能更新你的答案,以便我能准确地看到导致错误的原因吗?
【解决方案2】:

最后我选择了这种方法。当然,一切都可以更优雅,但现在这对我来说是可行的:

    if request.method == "POST":
    data = request.form.to_dict()

    result = 0

    for x in range(len(data)):

        check1 = int(list(data.keys())[x])
        check2 = quiz[x]['id_flashcard']
        check3 = list(data.values())[x]
        check4 = quiz[x]['word']

        if check1 == check2 and check3 == check4:
            result += 1

    add_quiz = db.execute("UPDATE languages SET quiz = quiz + 1 WHERE user_id = :user_id AND language = :quiz_language", user_id = user_id, quiz_language = quiz_language)
    avg = ((result / n_cards) * 100)
    update_quizzes = db.execute("INSERT INTO quizzes (user_id, language, n_flashcards, correct_answers, avg_quiz) VALUES (:user_id, :language, :n_flashcards, :correct_answers, :avg)", user_id = user_id, language = quiz_language, n_flashcards = n_cards, correct_answers = result, avg = avg)
    sum_avg_quizzes = db.execute("SELECT SUM(avg_quiz) as sum FROM quizzes WHERE user_id = :user_id AND language = :quiz_language", user_id = user_id, quiz_language = quiz_language)[0]["sum"]
    quiz_n = db.execute("SELECT COUNT(*) as count FROM quizzes WHERE user_id = :user_id AND language = :quiz_language", user_id = user_id, quiz_language = quiz_language)[0]["count"]
    tot_avg_quizzes = sum_avg_quizzes / quiz_n
    update_avg_quiz = db.execute("UPDATE languages SET average = :average WHERE user_id = :user_id AND language = :quiz_language", average = tot_avg_quizzes, user_id = user_id, quiz_language = quiz_language)

    return redirect("/quiz")

感谢您的帮助! :)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-03
    • 2012-01-05
    • 1970-01-01
    • 2020-08-24
    • 2020-05-24
    相关资源
    最近更新 更多