如何在不使用 JavaScript 的情况下更新 Flask 模板中的变量?

问题描述 投票:0回答:1

我正在尝试使用 Flask 制作一个图书馆管理项目,并具有书籍搜索功能。 Reference Image 如果我在搜索框中输入一些内容,我只想查看那些书。 这是我的 HTML

{% block content %}
<div class="search-area">
    <div class="input">
        <input class="search" type="text" id="search-box" placeholder="Search A Book" autocomplete="off">
        <img src="static/icons/search.svg">
    </div>
</div>

<main id="main-content">
    {% if search_term %}
      {% for book in books %}
        <div class="container">
          <div class="inner-containers" id="{{book['ID']}}" onclick="showReader('{{book['ID']}}')">
            <div class="image-container">
              <img draggable="false" class="book-image" src="{{ url_for('static', filename='thumbnails/' + book['Image']) }}">
            </div>
            <div class="book-details">
              <p class="name">{{ book['Name'] }}</p>
              <p class="author">{{ book['Author'] }}</p>
              <p class="details">{{ book['Date'] }} &#183; {{ book['Genre'] }}</p>
            </div>
          </div>
        </div>
      {% endfor %}
    {% else %}
      {% for book in original_books %}
        <div class="container">
          <div class="inner-containers" id="{{book['ID']}}" onclick="showReader('{{book['ID']}}')">
            <div class="image-container">
              <img draggable="false" class="book-image" src="{{ url_for('static', filename='thumbnails/' + book['Image']) }}">
            </div>
            <div class="book-details">
              <p class="name">{{ book['Name'] }}</p>
              <p class="author">{{ book['Author'] }}</p>
              <p class="details">{{ book['Date'] }} &#183; {{ book['Genre'] }}</p>
            </div>
          </div>
        </div>
      {% endfor %}
    {% endif %}
    
    <p class="section-title">This Month in Horror</p>
  </main>

{% endblock %}

我创建了一个Python函数来处理输入

@app.route('/home', methods=['GET', 'POST'])
def home():
  books = books_df.books.to_dict('records')
  original_books = books.copy()  # Assuming you want a copy for full data
  search_term = ''  # Initialize empty search term

  if request.method == 'POST':
    # Handle search term
    data = request.get_json()
    search_term = data.get('searchTerm', '').lower()  # Get and lowercase search term

    # Filter books based on search term (if provided)
    if search_term:
      filtered_books = books_df.books[books_df.books['Name'].str.lower().str.contains(search_term)]
      books = filtered_books.to_dict('records')
      print(books)
    return render_template('home.html', books=books, search_term = search_term)  # Pass both variables
  return render_template('home.html', original_books=original_books, search_term = None)

这是将其发送到 python 的 JS

<script>
        inputbox = document.getElementById('search-box');

        inputbox.addEventListener('keyup', () => {
        let input = inputbox.value.trim().toLowerCase();

        if (input.length) {
            // Create an XMLHttpRequest object
            const xhr = new XMLHttpRequest();
            xhr.open("POST", "/home"); // Replace with your actual endpoint

            // Set request headers (optional, but recommended for data format)
            xhr.setRequestHeader("Content-Type", "application/json");

            // Send the search term as JSON data
            xhr.send(JSON.stringify({ searchTerm: input }));
        }
    })
        
    </script>

JS 和 Python 都按预期工作,但是当我搜索时什么也没有发生。 Here是整个代码。谢谢。

python flask search
1个回答
0
投票

当您使用

XMLHttpRequest
fetch
时,您必须自行替换 HTML - 浏览不会自动替换它。它允许仅替换部分 HTML,而不是整个页面。

outputbox.innerHTML = new_HTML;

例如使用

fetch

        fetch("/search", {
            method: "POST", 
            headers: {
              "Content-Type": "application/json"
            },
            body: JSON.stringify({ searchTerm: input })
        })
        .then(response => response.text())
        .then(text => {outputbox.innerHTML = text;});

最少的工作代码:

我用现代的

fetch
代替旧的
XMLHttpRequest

我还使用

render_template_string
将所有代码放入一个文件中 - 这样每个人都可以简单地将所有代码复制到一个文件中来测试它。

from flask import Flask, request, render_template_string

app = Flask(__name__)

@app.route('/')
def index():
    return render_template_string('''<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <input id="search-box"/>
    <div id="output-box"></div>
<script>
outputbox = document.getElementById("output-box");
inputbox  = document.getElementById("search-box");

inputbox.addEventListener("keyup", () => {
    let input = inputbox.value.trim().toLowerCase();

    if (input.length) {
        fetch("/search", {
            method: "POST", 
            headers: {
              //"Accept": "application/json",
              "Content-Type": "application/json"
            },
            body: JSON.stringify({ searchTerm: input })
        })
        .then(response => response.text())
        //.then(text => alert(text))
        .then(text => {outputbox.innerHTML = text;});
    } else {
        outputbox.innerHTML = "";
    }
})
</script>
</body>
</html>''')

@app.route('/search', methods=['GET', 'POST'])
def image():
    if request.method == "POST":
        data = request.json
        #print('json:', data)
        search_term = data['searchTerm']
        results = [f'{x+1}: {search_term}' for x in range(3)]
        return render_template_string('{% for item in data %}<div>{{item}}</div>{% endfor %}', data=results)
    
    return ''

if __name__ == '__main__':
    app.debug = True 
    app.run()
© www.soinside.com 2019 - 2024. All rights reserved.