Flask+Python+SQLite中函数调用与星座计算入库问题求助
解决你的Flask+SQLite星座项目问题
核心问题分析
你遇到的错误主要来自三个方面:
- 路由中函数调用未正确接收返回值,导致变量未赋值
- 表单数据类型不匹配(字符串 vs 整数),星座计算逻辑失效
- 路由内的
return语句提前终止了代码执行,数据库插入操作未触发
步骤1:修复星座计算函数(helper.py)
首先修正zodiac_sign函数的类型判断和值比较问题,同时处理输入类型:
def zodiac_sign(day, month): # 确保输入是整数(表单传来的是字符串,需要转换) day = int(day) month = int(month) astro_sign = "" # 用==代替is(is判断对象身份,==判断值相等) if month == 12: astro_sign = "Sagittarius" if (day < 22) else "Capricorn" elif month == 1: astro_sign = "Capricorn" if (day < 20) else "Aquarius" elif month == 2: astro_sign = "Aquarius" if (day < 19) else "Pisces" elif month == 3: astro_sign = "Pisces" if (day < 21) else "Aries" elif month == 4: astro_sign = "Aries" if (day < 20) else "Taurus" elif month == 5: astro_sign = "Taurus" if (day < 21) else "Gemini" elif month == 6: astro_sign = "Gemini" if (day < 21) else "Cancer" elif month == 7: astro_sign = "Cancer" if (day < 23) else "Leo" elif month == 8: astro_sign = "Leo" if (day < 23) else "Virgo" elif month == 9: astro_sign = "Virgo" if (day < 23) else "Libra" elif month == 10: astro_sign = "Libra" if (day < 23) else "Scorpio" elif month == 11: astro_sign = "Scorpio" if (day < 22) else "Sagittarius" return astro_sign
步骤2:修复Register路由逻辑(application.py)
修正函数调用、数据类型转换和代码执行顺序问题:
# 先导入helper里的函数 from helper import zodiac_sign from flask import Flask, render_template, request, session, redirect, url_for, apology from werkzeug.security import generate_password_hash # 假设你用这个加密密码 import sqlite3 # 初始化数据库连接(根据你的实际配置调整) db = sqlite3.connect("signs.db", check_same_thread=False) db.row_factory = sqlite3.Row # 你的其他Flask初始化代码... @app.route("/register", methods=["GET", "POST"]) def register(): """Register user""" if request.method == "POST": username = request.form.get("username") month = request.form.get("month") day = request.form.get("day") password = request.form.get("password") confirm_password = request.form.get("confirm_password") # 补充密码确认逻辑 # 基础校验 if not username: return apology("must provide username", 400) if not day or not month: return apology("must provide birthday", 400) if not password or password != confirm_password: return apology("passwords do not match", 400) # 转换生日为整数并校验合法性 try: day = int(day) month = int(month) if month < 1 or month > 12 or day < 1 or day > 31: return apology("invalid birthday", 400) except ValueError: return apology("birthday must be numbers", 400) # 计算星座 astro_sign = zodiac_sign(day, month) # 插入用户到users表 try: db.execute("INSERT INTO users (username, hash, month, day) VALUES (:username, :password, :month, :day)", username=username, password=generate_password_hash(password), month=month, day=day) db.commit() # 手动提交事务 except db.IntegrityError: return apology("username is already registered", 400) # 获取新注册用户的ID user_id = db.execute("SELECT id FROM users WHERE username = :username", username=username).fetchone()["id"] session["user_id"] = user_id # 插入星座到signs表 db.execute("INSERT INTO signs (user_id, astro_sign) VALUES (:user_id, :astro_sign)", user_id=session["user_id"], astro_sign=astro_sign) db.commit() # 重定向到登录页或首页 return redirect(url_for("login")) else: return render_template("register.html")
关键修复点:
- 调用
zodiac_sign时接收返回值,并确保传入的是整数类型 - 移除了中间的
return astro_sign语句(它会提前终止代码,导致数据库插入失败) - 添加了数据库事务的
commit()操作(SQLite默认需要手动提交) - 补充了基础参数校验,避免非法数据进入数据库
步骤3:在index.html展示星座信息
在首页路由中查询用户的星座数据,传给模板:
@app.route("/") def index(): if "user_id" not in session: return redirect(url_for("login")) # 查询用户的星座 sign_data = db.execute("SELECT astro_sign FROM signs WHERE user_id = :user_id", user_id=session["user_id"]).fetchone() astro_sign = sign_data["astro_sign"] if sign_data else "Unknown" # 可选:同时获取用户名展示 user_data = db.execute("SELECT username FROM users WHERE id = :user_id", user_id=session["user_id"]).fetchone() username = user_data["username"] if user_data else "User" return render_template("index.html", username=username, astro_sign=astro_sign)
然后在index.html中展示:
{% extends "layout.html" %} {% block main %} <div class="container mt-5"> <h1>Welcome back, {{ username }}!</h1> <div class="mt-3"> <p>Your zodiac sign is: <strong class="text-primary">{{ astro_sign }}</strong></p> </div> </div> {% endblock %}
常见问题排查
- helper.py导入崩溃:确保helper.py和application.py在同一目录下,且导入语句正确(
from helper import zodiac_sign) - 数据库存入空值:检查
zodiac_sign函数是否正确返回值,可在调用后添加print(astro_sign)调试 - 路由重定向失败:确保
url_for("login")对应的路由存在,且拼写正确 - 数据库事务问题:所有插入/更新操作后必须调用
db.commit(),否则数据不会写入数据库
内容的提问来源于stack exchange,提问作者Kelly5978
相关产品推荐
相关产品推荐

