我正在使用带有sql-alchemy数据库的flask创建一个网站。我有三个带有外键互相引用的表。如何通过引用两个外键从第一张表中获取用户名和电话?我的代码如下:
models.py
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(60), unique=True, nullable=False)
phone = db.Column(db.Integer, nullable=True)
user_role = db.Column(db.String(20), nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
pgs = db.relationship('PGInfo', backref='owner', lazy=True)
bookedpgs = db.relationship('PGBooked', backref='customer', lazy=True)
def __repr__(self):
return f"User('{self.username}', '{self.email}')"
class PGInfo(db.Model):
id = db.Column(db.Integer, primary_key=True)
owner_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
pg_name = db.Column(db.String(200), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
location_info = db.Column(db.String(120), unique=True, nullable=False)
body = db.Column(db.Text, nullable=False)
price = db.Column(db.Integer, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
def __repr__(self):
return f"PGInfo('{self.pg_name}', '{self.date_posted}', '{self.location_info}', '{self.price}', '{self.image_file}')"
class PGBooked(db.Model):
id = db.Column(db.Integer, primary_key=True)
customer_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
pg_id = db.Column(db.Integer, db.ForeignKey(PGInfo.id), nullable=False)
def __repr__(self):
return f"PGBooked('{self.name}')"
routes.py
def book_pg(pg_id):
bookedpg = PGBooked(customer=current_user, owner=PGInfo.owner_id.username, pg_name=PGInfo.pg_name, location=PGInfo.location_info, phone=PGInfo.owner_id.phone)
db.session.add(bookedpg)
db.session.commit()
flash("You have booked the pg!", 'success')
return render_template('bookpg.html', title='Book PG')
bookpg.html
{% extends "layout.html" %}
{% block content %}
{{ bookedpg.customer }}
{{ bookedpg.owner }}
{{ bookedpg.pg_name }}
{{ bookedpg.location }}
{{ bookedpg.phone }}
{% endblock content %}
错误
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with PGInfo.owner_id has an attribute 'username'
那么如何根据上述关系获取用户名?预先谢谢你!
答案 0 :(得分:0)
错误出在 models.py 文件中。正确的代码如下:
models.py
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(200), unique=True, nullable=False)
email = db.Column(db.String(200), unique=True, nullable=False)
password = db.Column(db.String(60), unique=True, nullable=False)
phone = db.Column(db.Integer, nullable=True)
user_role = db.Column(db.String(20), nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
pgs = db.relationship('PGInfo', backref='owner', lazy=True)
bookedpgs = db.relationship('PGBooked', backref='customer', lazy=True)
def __repr__(self):
return f"User('{self.username}', '{self.email}')"
class PGInfo(db.Model):
id = db.Column(db.Integer, primary_key=True)
owner_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
pg_name = db.Column(db.String(200), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
location_info = db.Column(db.String(200), nullable=False)
body = db.Column(db.Text, nullable=False)
price = db.Column(db.Integer, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
pg = db.relationship('PGBooked', backref='pg', lazy=True)
def __repr__(self):
return f"PGInfo('{self.pg_name}', '{self.date_posted}', '{self.location_info}', '{self.price}', '{self.image_file}')"
class PGBooked(db.Model):
id = db.Column(db.Integer, primary_key=True)
customer_id = db.Column(db.Integer, db.ForeignKey('user.id'))
pg_id = db.Column(db.Integer, db.ForeignKey(PGInfo.id))
name = db.Column(db.String(200), nullable=False)
location_info = db.Column(db.String(200), nullable=False)
owner = db.Column(db.String(200), nullable=False)
phone = db.Column(db.Integer)
def __repr__(self):
return f"PGBooked('{self.name}')"
我必须在PGInfo表和PGBooked表之间创建一个关系。
routes.py
@app.route("/pg/<int:pg_id>/book_pg", methods=['GET','POST'])
@login_required
def book_pg(pg_id):
if current_user.is_authenticated:
pg = PGInfo.query.get_or_404(pg_id)
bookedpg = PGBooked(customer=current_user, name=pg.pg_name, location_info=pg.location_info, owner=pg.owner.username, phone=pg.owner.phone)
db.session.add(bookedpg)
db.session.commit()
# db.session.delete(pg)
# db.session.commit()
flash("You have booked the pg!", 'success')
return redirect(url_for('display_booked_pgs'))
@app.route("/booked_pgs", methods=['GET', 'POST'])
@login_required
def display_booked_pgs():
bookedpgs = PGBooked.query.filter_by(customer_id=current_user.id).all()
# bookedpgs_dict = dict((col, getattr(bookedpgs, col)) for col in bookedpgs.__table__.columns.keys())
return render_template('bookedpg.html', title='Booked PGs', bookedpgs=bookedpgs)
然后我可以通过如下循环显示在模板中:
bookpg.html
{% extends "layout.html" %}
{% block content %}
<div>
{% for item in bookedpgs %}
<p> {{ item.__dict__ }} </p>
{% endfor %}
</div>
{% endblock content %}