我在flask应用程序中有两个模型,它们形成一对一的关系,其中“ Staff”模型可以与一个“ User”关联。可以有“工作人员”而不让他们成为“用户”,但不能有“用户”而不是“工作人员”。
不幸的是,我遇到了第一个障碍。我正在尝试将模型合并到通过Jinja2模板化的HTML表中。该表应列出所有“工作人员”,并确定它们是否为“用户”。如果它们是“用户”,则应该确定它们是否处于活动状态。
这是我目前的模特:
class Staff(db.Model):
__tablename__ = 'staff'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
job_title = db.Column(db.String(255), nullable=True)
is_user = db.Column(db.Boolean, nullable=False, default=False)
user = db.relationship('User',
backref=db.backref('staff', lazy=True))
def __repr__(self):
return f'Staff Member: {self.id}, {self.name}, {self.job_title}'
class User(db.Model, UserMixin):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False,
default='default.jpg')
password = db.Column(db.String(255), nullable=False)
active = db.Column(db.Boolean, nullable=False, default=False)
staff_id = db.Column(db.Integer, db.ForeignKey('staff.id'),
nullable=False)
def __repr__(self):
return f'User({self.name}, {self.email}, {self.image_file})'
这是Jinja2中的关系示例。该代码段按预期工作:
{% for user in users %}
<tr>
<td>{{ user.staff.name }}</td>
<td>{{ user.staff.job_title }}</td>
<td>{{ user.email }}</td>
{% if user.active == True %}
<td>Yes</td>
{% else %}
<td>No</td>
{% endif %}
{% endfor %}
但是,这段代码在遍历所有“工作人员”时试图获取“用户”详细信息的地方根本不起作用:
{% for staff in all_staff %}
<tr>
<td>{{ staff.name }}</td>
<td>{{ staff.job_title }}</td>
{% if staff.is_user == True %}
{% if staff.user.active == True %}
<td class="text-success">Yes (Active)</td>
{% elif staff.user.active == False %}
<td class="text-warning">Yes (Inactive)</td>
{% endif %}
{% elif staff.is_user == False %}
<td class="text-danger">No</td>
{% endif %}
{% endfor %}
虽然关系在第二个表格示例中以一种无效的方式起作用;除非staff.is_user == False语句为true,否则它根本不返回任何HTML代码。
我试图在'User'类中创建一个新的db.relationship。我也在两个类中一次尝试了db.relationship。我也尝试过在同一行上的Jinja2 if语句:
{% if staff.is_user == True and staff.user.active == True %}
但是这些都不起作用,并且我希望根据if语句的结果返回正确的html,通过“ Users”表引用时,我根本没有任何结果。 “员工桌。
我确定我缺少一些简单的东西,但我无法弄清楚。
有人可以看到我要去哪里吗?
答案 0 :(得分:0)
事实证明,答案隐藏在Flask-SQLAlchemy docs的“一对五关系”部分中。为了引用一对一关系,您需要在该关系中设置uselist=False
。听起来确实如此,它将连接作为标量而不是列表加载。
在从SQLAlchemy主文档中获取一些信息并且未正确加载关系中的backref时,我也犯了一个错误。在Flask-SQLAlchemy中,只需将其声明为字符串即可。在这种情况下,backref='staff'
。
此代码完全按预期工作:
class Staff(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True, nullable=False)
job_title = db.Column(db.String(80))
is_user = db.Column(db.Boolean, default=False)
user = db.relationship('User', backref='staff', lazy=True, uselist=False)
def __repr__(self):
return f'Staff Member: {self.id}, {self.name}, {self.job_title}'
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, nullable=False)
active = db.Column(db.Boolean, nullable=False, default=False)
staff_id = db.Column(db.Integer, db.ForeignKey('staff.id'), nullable=False)
def __repr__(self):
return f'User Account: {self.id}, {self.email}'