为了实现将宠物ID从表单和查询中移除,并统一使用宠物名字来操作宠物数据,需要对现有的代码进行以下修改:
### 1. 修改数据库结构
首先,需要修改数据库表结构,使得 `pets` 表中的 `id` 字段不再作为主键,而是使用 `pet_name` 作为唯一标识符。
```python
def init_db():
conn = connect_db()
cursor = conn.cursor()
# 修改 pets 表结构
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS pets (
user_id INT NOT NULL,
pet_name VARCHAR(255) NOT NULL,
PRIMARY KEY (user_id, pet_name),
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS pet_weights (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
pet_name VARCHAR(255) NOT NULL,
weight DECIMAL(10, 2) NOT NULL,
recorded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id, pet_name) REFERENCES pets (user_id, pet_name) ON DELETE CASCADE
)
''')
conn.commit()
conn.close()
```
### 2. 修改路由和函数
接下来,需要修改所有涉及宠物ID的地方,改为使用宠物名字。
#### 2.1 修改 `add_pet` 路由
```python
@app.route('/add_pet', methods=['GET', 'POST'])
def add_pet():
if 'user_id' not in session:
return redirect(url_for('login'))
if request.method == 'POST':
user_id = session['user_id']
pet_name = request.form['pet_name']
weight = float(request.form['weight'])
conn = connect_db()
cursor = conn.cursor()
try:
cursor.execute('INSERT INTO pets (user_id, pet_name) VALUES (%s, %s)', (user_id, pet_name))
cursor.execute('INSERT INTO pet_weights (user_id, pet_name, weight) VALUES (%s, %s, %s)', (user_id, pet_name, weight))
conn.commit()
flash(f"宠物 {pet_name} 添加成功,初始体重为 {weight:.2f} kg", 'success')
logging.info("宠物 %s 添加成功,初始体重为 %.2f kg", pet_name, weight)
except mysql.connector.IntegrityError:
flash("该宠物名称已存在!", 'warning')
logging.warning("该宠物名称 %s 已存在!", pet_name)
finally:
conn.close()
return redirect(url_for('dashboard'))
return render_template('add_pet.html')
```
#### 2.2 修改 `view_pet` 路由
```python
@app.route('/view_pet/<string:pet_name>')
def view_pet(pet_name):
if 'user_id' not in session:
return redirect(url_for('login'))
user_id = session['user_id']
conn = connect_db()
cursor = conn.cursor()
cursor.execute('SELECT pet_name FROM pets WHERE user_id = %s AND pet_name = %s', (user_id, pet_name))
pet = cursor.fetchone()
if not pet:
flash("宠物不存在!", 'warning')
logging.warning("宠物不存在!")
return redirect(url_for('dashboard'))
cursor.execute('SELECT weight, recorded_at FROM pet_weights WHERE user_id = %s AND pet_name = %s ORDER BY recorded_at', (user_id, pet_name))
weights = cursor.fetchall()
conn.close()
return render_template('view_pet.html', pet=pet, weights=weights)
```
#### 2.3 修改 `update_pet_weight` 路由
```python
@app.route('/update_pet_weight/<string:pet_name>', methods=['GET', 'POST'])
def update_pet_weight(pet_name):
if 'user_id' not in session:
return redirect(url_for('login'))
user_id = session['user_id']
conn = connect_db()
cursor = conn.cursor()
# 获取当前宠物的所有体重记录
cursor.execute('SELECT weight, recorded_at FROM pet_weights WHERE user_id = %s AND pet_name = %s ORDER BY recorded_at DESC', (user_id, pet_name))
weights = cursor.fetchall()
if request.method == 'POST':
weight = float(request.form['weight'])
cursor.execute('INSERT INTO pet_weights (user_id, pet_name, weight) VALUES (%s, %s, %s)', (user_id, pet_name, weight))
conn.commit()
flash("宠物体重更新成功!", 'success')
logging.info("宠物体重更新成功!")
conn.close()
return redirect(url_for('view_pet', pet_name=pet_name))
conn.close()
return render_template('update_pet_weight.html', pet_name=pet_name, weights=weights)
```
### 3. 修改模板文件
最后,需要修改相关的HTML模板文件,将所有的宠物ID替换为宠物名字。
#### `add_pet.html`
```html
<form method="post">
<label for="pet_name">宠物名称:</label>
<input type="text" name="pet_name" required>
<br>
<label for="weight">初始体重 (kg):</label>
<input type="number" step="0.01" name="weight" required>
<br>
<button type="submit">添加宠物</button>
</form>
```
#### `view_pet.html`
```html
<h1>宠物: {{ pet[0] }}</h1>
<table>
<tr>
<th>体重 (kg)</th>
<th>记录时间</th>
</tr>
{% for weight, recorded_at in weights %}
<tr>
<td>{{ weight }}</td>
<td>{{ recorded_at }}</td>
</tr>
{% endfor %}
</table>
<a href="{{ url_for('update_pet_weight', pet_name=pet[0]) }}">更新体重</a>
```
#### `update_pet_weight.html`
```html
<h1>更新宠物体重: {{ pet_name }}</h1>
<form method="post">
<label for="weight">新体重 (kg):</label>
<input type="number" step="0.01" name="weight" required>
<br>
<button type="submit">更新体重</button>
</form>
```
通过以上修改,可以实现使用宠物名字而不是ID来管理宠物数据的功能。