Python __str__方法未返回预期结果,Flask展示MSSQL数据异常
Flask中SQLAlchemy模型__str__方法不生效的问题解决
我学习Python已有几周时间,正在修改课程中的代码。已将数据存入MSSQL数据库,希望在Flask页面中展示该数据表。按照要求为Products类添加了__str__方法,但仍未得到预期的字符串输出。
原代码
app.py
from flask import Flask, render_template, url_for, redirect from flask_migrate import Migrate from flask_sqlalchemy import SQLAlchemy from sqlalchemy import create_engine app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "mssql://@UB-tucIMS9NpXKF\SQLEXPRESS/LOCAL_UBBI?driver=ODBC Driver 17 for SQL Server" app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db = SQLAlchemy(app) Migrate(app,db) db.init_app(app) class Products(db.Model): __tablename__ = 'Products' id = db.Column(db.Integer,primary_key=True) Name = db.Column(db.Text) Code = db.Column(db.Integer) def __init__(self,id, name, code): self.id = id self.name = name self.code = code def __str__(self): return f"Product: ('number {self.id} is: {self.name}, {self.code}')" @app.route('/') def index(): return render_template('home.html') @app.route('/products') def listProducts(): myProducts = Products.query.all() return render_template('listProducts.html', myProducts=myProducts) if __name__ == '__main__': app.run(debug=True)
listProducts.html
{% extends "base.html" %} {% block content %} <div class="jumbotron"> <p>list products</p> {{ myProducts }} <!--{{ myProducts.name }}--> <!--<ul> {% for eachproduct in myProducts %} <li>{{eachproduct}}</li> {% endfor %} </ul>--> </div> {% endblock %}
问题根源
- 方法缩进错误:
__init__和__str__方法未缩进在Products类内部,成为了全局函数,而非类的成员方法,导致SQLAlchemy无法识别__str__。 - 字段名大小写不匹配:数据库列名为
Name和Code,但__init__中使用小写name和code,实例属性与数据库字段无法正确映射,即使__str__生效也无法获取正确值。 - 多余的手动构造方法:SQLAlchemy的
db.Model已自动生成构造方法,手动编写__init__反而容易引入错误。
修正后的代码
app.py 修正版
from flask import Flask, render_template, url_for, redirect from flask_migrate import Migrate from flask_sqlalchemy import SQLAlchemy from sqlalchemy import create_engine app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "mssql://@UB-tucIMS9NpXKF\SQLEXPRESS/LOCAL_UBBI?driver=ODBC Driver 17 for SQL Server" app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False db = SQLAlchemy(app) Migrate(app, db) db.init_app(app) class Products(db.Model): __tablename__ = 'Products' id = db.Column(db.Integer, primary_key=True) Name = db.Column(db.Text) Code = db.Column(db.Integer) # 使用SQLAlchemy默认构造方法,移除手动__init__ def __str__(self): return f"Product: (number {self.id} is: {self.Name}, {self.Code})" @app.route('/') def index(): return render_template('home.html') @app.route('/products') def listProducts(): myProducts = Products.query.all() return render_template('listProducts.html', myProducts=myProducts) if __name__ == '__main__': app.run(debug=True)
listProducts.html 修正版
需取消循环注释,直接输出列表只会显示对象默认表示,循环每个对象才会触发__str__:
{% extends "base.html" %} {% block content %} <div class="jumbotron"> <p>list products</p> <ul> {% for eachproduct in myProducts %} <li>{{ eachproduct }}</li> {% endfor %} </ul> </div> {% endblock %}
关键说明
- 将
__str__正确缩进在Products类内部,确保它是类的成员方法。 - 移除手动
__init__,依赖SQLAlchemy自动构造方法处理字段赋值,避免大小写匹配错误。 - 视图中循环遍历产品列表,每个对象渲染时会自动调用
__str__,输出自定义格式字符串。
内容的提问来源于stack exchange,提问作者Dennis Schlein
相关产品推荐
相关产品推荐

