开始一个新项目,想要列出 sqlite 数据库的所有联系人。 我使用flask、js、html和jinja2。
我的 HTML 基于layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
<title>Buchhaltung - {% block title %}{% endblock %}</title>
</head>
<body>
<header>
<nav class="menu">
<ul>
<li><a href="{{ url_for('index') }}">Home</a></li>
<li><a href="{{ url_for('list_addresses', starting_letter='ALL') }}">Kontakte</a></li>
<li><a href="{{ url_for('list_invoices') }}">Rechnungen</a></li>
<!-- Add links for other menu items -->
<!-- ... -->
</ul>
</nav>
</header>
<div class="content" id="content">
{% block content %}{% endblock %}
</div>
<footer>
</footer>
<script src="{{ url_for('static', filename='script.js') }}"></script>
</body>
</html>`
我的地址列表继承自这个layout.html
`` `
{% extends 'layout.html' %}
<!--
{% block title %}Address List{% endblock %}
-->
{% block content %}
<div>
<h1>Kontakt Liste</h1>
{% include 'address_filter.html' %}
</div>
<div>
{% include 'address_result.html' %}
</div>
{% endblock %}`
``
address_filter.html 包含一行从 a-z 的字母和一个用于过滤地址列表的复选框。
``
<div class="row">
<div class="starting-letters-row">
<button class="all-button" onclick="filterAddressesByStartingLetter('ALL')">ALLE</button>
{% for letter in starting_letters %}
<button onclick="filterAddressesByStartingLetter('{{ letter }}')">{{ letter }}</button>
{% endfor %}
</div>
<div class="filter-active">
<label for="filter-active">Show Active only:</label>
<input type="checkbox" id="filter-active" {% if filter_active != 'false' %}checked{% endif %} onchange="filterAddressesByStartingLetter('ALL')">
</div>
</div>
``
**address_result.html 保存结果表。
Flask 实现如下所示 **
from flask import Flask, render_template, g, request, send_from_directory
import sqlite3
from datetime import datetime, timedelta
app = Flask(__name__)
# Function to get the database connection
def get_db():
if 'db' not in g:
g.db = sqlite3.connect('data/rechnung.db')
g.cursor = g.db.cursor()
return g.db, g.cursor
# Close the database connection at the end of each request
@app.teardown_appcontext
def close_db(error):
if 'db' in g:
g.db.close()
# Route to render the home page
@app.route('/')
def index():
return render_template('index.html')
def addresses_retrieve_startLetter():
db, cursor = get_db()
# Retrieve unique starting letters for names (active and inactive to define the maximum letter row)
cursor.execute('SELECT DISTINCT substr(adr_name, 1, 1) FROM adressen ORDER BY substr(adr_name, 1, 1)' )
starting_letters = [letter[0] for letter in cursor.fetchall()]
return starting_letters
# Route to display addresses for a specific starting letter
@app.route('/addresses/<starting_letter>', methods=['GET', 'POST'])
def list_addresses(starting_letter):
db, cursor = get_db()
#Get the filter_active parameter from the URL
filter_active = request.args.get('filter_active', type=bool)
if filter_active == 'true' or filter_active is None:
filter_active_arg = 1
else:
filter_active_arg = 0
starting_letters = addresses_retrieve_startLetter()
# Define Headers
headers = ['Name', 'Vorname', 'Firma', 'Ort', 'eMail', 'Id']
# Retrieve addresses from the database for the selected starting letter
# If starting_letter is 'ALL', retrieve all addresses
if starting_letter.upper() == 'ALL':
cursor.execute('SELECT adr_name, adr_vorname, adr_firma, adr_ort, adr_email, adr_id FROM adressen WHERE adr_aktiv = ? ORDER BY adr_name', (filter_active_arg,))
else:
cursor.execute('SELECT adr_name, adr_vorname, adr_firma, adr_ort, adr_email, adr_id FROM adressen WHERE substr(adr_name, 1, 1) = ? and adr_aktiv =?', (starting_letter,filter_active_arg,))
addresses = cursor.fetchall()
# app.logger.info(addresses)
return render_template('list_addresses.html', starting_letters= starting_letters, headers=headers, addresses=addresses, filter_active=filter_active)`
当启动服务器并打开我的页面时,导航会显示一次。
单击字母或复选框即可过滤列表 导航会重复。
GIT COpilot 告诉我解决方案..我替换了整个页面,而不是仅替换了新更改的数据对象
fetch(`/addresses/${startingLetter}?filter_active=${filterActive}`)
.then(response => response.text())
.then(html => {
// Create a temporary div to hold the HTML response
var tempDiv = document.createElement('div');
tempDiv.innerHTML = html;
// Extract the 'addressList' part from the response
var newAddressList = tempDiv.querySelector('#addressList');
// Replace the existing 'addressList' with the new one
var oldAddressList = document.querySelector('#content #addressList');
oldAddressList.parentNode.replaceChild(newAddressList, oldAddressList);
})
.catch(error => console.error('Error:', error));
};