使用 SQLAlchemy 提交表单抛出 'list' 对象没有属性
Submitting a form with SQLAlchemy throws 'list' object has no attribute
我对 Flask 和 SQLAlchemy 以及编码都是新手,所以请耐心等待。
我想做的是通过表单将数据发送到我的数据库。
工作正常,直到我想要另外两个具有一对多关系的 table,因为在 植物中可以积累许多元素并且植物可以具有许多属性 并且烧瓶抛出错误 AttributeError: 'list' 对象没有属性 '_sa_instance_state'.
形式是:
from flask_wtf import FlaskForm
from wtforms.ext.sqlalchemy.fields import QuerySelectMultipleField
from wtforms import StringField, PasswordField, SubmitField,BooleanField, TextAreaField
#Query for Dynamic Nutrient Accumulator Model
def enabled_dna():
return DNA.query.all()
#Query for Nitrogen Fixers Nursing Model
def enabled_nfn():
return NFN.query.all()
class NewPlantForm(FlaskForm):
common_name = StringField('Common Name', render_kw={"placeholder": "Common name"},
validators=[DataRequired(), Length(min=2, max=40)])
botanical_name = StringField('Botanical Name', render_kw={"placeholder": "Botanical name"},
validators=[DataRequired(), Length(min=2, max=80)])
short_description = TextAreaField('Short Description', render_kw={"placeholder": "Please add a short description"},
validators=[DataRequired()])
medicinal = TextAreaField('Medicinal Use', render_kw={"placeholder": "Medicinal use"},
validators=[DataRequired()])
dna = QuerySelectMultipleField('Select Element',query_factory=enabled_dna,allow_blank=True)
nfn = QuerySelectMultipleField('Select Property',query_factory=enabled_nfn,allow_blank=True)
submit = SubmitField('Add plant')
models.py 看起来像这样:
#Plants Table
class Plants(db.Model):
id = db.Column(db.Integer, primary_key=True)
common_name = db.Column(db.String(40), nullable=False)
botanical_name = db.Column(db.String(80), unique=True, nullable=False)
short_description = db.Column(db.Text, nullable=False)
medicinal = db.Column(db.Text, nullable=False)
image_file = db.Column(db.String(20), default='default_plant_pic.jpg')
date_added = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
dna_id = db.Column(db.Integer, db.ForeignKey('DNA.id'))
dna = db.relationship('DNA', backref=db.backref('plant_dna', lazy='dynamic')) # Dynamic_Nutrient_Accumulated
nfn_id = db.Column(db.Integer, db.ForeignKey('NFN.id'))
nfn = db.relationship('NFN', backref=db.backref('plant_nfn', lazy='dynamic')) # Nitrogen_Fixers_Nursing
def __repr__(self):
return f"Plants('{self.common_name}', '{self.botanical_name}', '{self.short_description}'," \
f" '{self.medicinal}', '{self.dna}', '{self.nfn}' )"
#Dynamic_Nutrient_Accumulated
class DNA(db.Model):
id = db.Column(db.Integer, primary_key=True)
element = db.Column(db.String(15))
def __repr__(self):
return '[ {}]'.format(self.element)
#Nitrogen_Fixers_Nursing
class NFN(db.Model):
id = db.Column(db.Integer, primary_key=True)
plant_extra = db.Column(db.String(40))
def __repr__(self):
return '[ {}]'.format(self.plant_extra)
路由和表单与仅包含一个字段的表单一起工作正常table。但是,当我添加包含来自其他 tables(form.dna.data 和 form.nfn.data)的数据的第二个和第三个字段时,它现在不起作用。
我的新工厂路线是:
@app.route("/plants/new/", methods=['GET', 'POST'])
@login_required# User must be logged in to create a new plant
def new_plant():
form = NewPlantForm()
if form.validate_on_submit():
new_plant = Plants(common_name=form.common_name.data,
botanical_name=form.botanical_name.data,
short_description=form.short_description.data,
medicinal=form.medicinal.data,
dna=form.dna.data,
nfn=form.nfn.data,
author=current_user)
db.session.add(new_plant)
db.session.commit()
flash('Thank you ! You have successfully added a plant '
'to the database!', 'success')
return redirect(url_for('plants'))
image_file = url_for('static', filename='img/plants/default_plant_pic.jpg')
return render_template('new_plant.html', title='Add new plant',
image_file=image_file, form=form)
渲染植物信息的路径是:
@app.route("/plants")
def plants():
plants = Plants.query.all()
return render_template('plants.html', title= 'Plants Database', plants=plants)
我已经尝试从终端在本地使用它并且它有效,但我不知道我遗漏了什么或者关系模型是否错误以使其从 Flask 应用程序运行。
在此先感谢您的耐心等待和帮助。
更新
经过反复试验,现在似乎一切正常(将具有 selected 字段的植物添加到数据库,将植物数据正确渲染到模板中,植物被正确添加到在我将 QuerySelectMultipleField 更改为 QuerySelectField 之后,使用 SQLite 的数据库浏览器查看数据库)。但是,我的意思是能够 select 并呈现多个选择。
我注意到的另一件事是,当使用 QuerySelectField 时,模板会正确呈现下拉列表,但是当尝试使用 QuerySelectMultipleField,它只呈现一个包含元素的列表,没有下拉列表。
这是模板的一小部分 select 字段 form.dna 和 form.nfn:
<div class="form-group">
{{ form.dna(class="form-control form-control-sm") }}
</div>
<div class="form-group">
{{ form.nfn(class="form-control form-control-sm")}}
</div>
我正在使用 Bootstrap。这件事可能与为多个 select 编写的模板格式不正确有关吗?
谢谢。
更新2
我设法让 QuerySelectMultipleField 通过像这样遍历表单数据来工作:
@app.route("/plants/new/", methods=['GET', 'POST'])
@login_required# User must be logged in to create a new plant
def new_plant():
form = NewPlantForm()
if form.validate_on_submit():
new_plant = Plants(common_name = form.common_name.data, botanical_name = form.botanical_name.data,
short_description = form.short_description.data, medicinal=form.medicinal.data,
author=current_user)
**for dna_element in form.dna.data:
new_plant.dna = dna_element
for nfn_element in form.nfn.data:
new_plant.nfn = nfn_element**
db.session.add(new_plant)
db.session.commit()
flash(f'Thank you ! You have successfully added a plant to the database!', 'success')
return redirect(url_for('plants'))
image_file = url_for('static', filename='img/plants/default_plant_pic.jpg')
return render_template('new_plant.html', title='Add new plant',
image_file=image_file, form=form)
我不再收到错误 AttributeError: 'list' object has no attribute '_sa_instance_state' 并且植物已成功添加到数据库中,但是当我查看数据库时,我可以看到只有一个选项是 selected,而不是多个选项。
根据我在这里阅读的内容: Flask App Using WTForms with SelectMultipleField ,我应该使用 form.something.data 来获取我所做的项目列表,但仍然不起作用我只得到一件物品。
请帮忙。
谢谢!
更新 3 并解决问题
执行 sleblanc 的 响应后,我现在有以下代码可以与表单一起使用并正确显示:
**models.py : **
plants_dna_table = db.Table(
'plants_dna',
db.Column('plants_id', db.Integer, db.ForeignKey('plants.id'), nullable=False),
db.Column('dna_id', db.Integer, db.ForeignKey('DNA.id'), nullable=False),
db.UniqueConstraint('plants_id', 'dna_id'))
plants_nfn_table = db.Table(
'plants_nfn',
db.Column('plants_id', db.Integer, db.ForeignKey('plants.id'), nullable=False),
db.Column('nfn_id', db.Integer, db.ForeignKey('NFN.id'), nullable=False),
db.UniqueConstraint('plants_id', 'nfn_id'))
#Plants Table
class Plants(db.Model):
id = db.Column(db.Integer, primary_key=True)
common_name = db.Column(db.String(40), nullable=False)
botanical_name = db.Column(db.String(80), unique=True, nullable=False)
short_description = db.Column(db.Text, nullable=False)
medicinal = db.Column(db.Text, nullable=False)
image_file = db.Column(db.String(20), default='default_plant_pic.jpg')
date_added = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
dna = db.relationship('DNA', secondary = plants_dna_table) # Dynamic_Nutrient_Accumulated
nfn = db.relationship('NFN', secondary = plants_nfn_table) # Nitrogen_Fixers_Nursing
def __repr__(self):
return f"Plants('{self.common_name}', '{self.botanical_name}', '{self.short_description}'," \
f" '{self.medicinal}', '{self.dna}', '{self.nfn}' )"
#Dynamic_Nutrient_Accumulated
class DNA(db.Model):
id = db.Column(db.Integer, primary_key=True)
element = db.Column(db.String(15))
def __repr__(self):
return '{}'.format(self.element)
#Nitrogen_Fixers_Nursing
class NFN(db.Model):
id = db.Column(db.Integer, primary_key=True)
plant_extra = db.Column(db.String(40))
def __repr__(self):
return '{}'.format(self.plant_extra)
用大写字母显示的 db.ForeignKey('DNA.id') 完成了工作,不会出现找不到 table 的错误DNA.
**routes.py : **
#Route for users to add a plant to the database
@app.route("/plants/new/", methods=['GET', 'POST'])
@login_required# User must be logged in to create a new plant
def new_plant():
form = NewPlantForm()
if form.validate_on_submit():
new_plant = Plants(common_name = form.common_name.data, botanical_name = form.botanical_name.data,
short_description = form.short_description.data, medicinal=form.medicinal.data,
author=current_user)
for dna_element in form.dna.data:
new_plant.dna.append(dna_element)
for nfn_element in form.nfn.data:
new_plant.nfn.append(nfn_element)
print(new_plant)
db.session.add(new_plant)
db.session.commit()
flash(f'Thank you ! You have successfully added a plant to the database!', 'success')
return redirect(url_for('plants'))
image_file = url_for('static', filename='img/plants/default_plant_pic.jpg')
return render_template('new_plant.html', title='Add new plant',
image_file=image_file, form=form)
谢谢@sleblanc!
您已经建立了相反的关系模型。
如果我没记错的话,你的植物与你的 DNA 和 NFN 之间存在一对多关系,这意味着一个 'Plants' 对象将具有多个 DNA 和多个 NFN。根据定义,您的 'Plants' 模型只有一个 DNA 字段和一个 NFN 字段,这意味着无法将关联存储在数据库中。
您将需要修改您的 Plants 模型以表示该关系。您必须首先确定 'DNA' 或 'NFN' 是否可以由多个 'Plants' 共享,或者它们是否对于每个 'Plants' 实例都是唯一的,因为它涉及不同的模式。
class Plants(db.Model):
id = db.Column(db.Integer, primary_key=True)
...
# second option, exclusive relationship
class DNA(db.Model):
id = db.Column(db.Integer, primary_key=True)
...
plants_id = db.Column(db.ForeignKey(Plants.id), nullable=False)
...
class NFN(db.Model):
id = db.Column(db.Integer, primary_key=True)
...
plants_id = db.Column(db.ForeignKey(Plants.id), nullable=False)
...
# first option, non-exclusive relationship
class Plants(db.Model):
...
dna = relationship("DNA", secondary=plants_dna_table)
nfn = relationship("NFN", secondary=plants_nfn_table)
plants_dna_table = db.Table(
'plants_dna',
db.Column('plants_id', db.ForeignKey('plants.id'), nullable=False),
db.Column('dna_id', db.ForeignKey('dna.id'), nullable=False),
db.UniqueConstraint('plants_id', 'dna_id'),
)
plants_nfn_table = db.Table(
'plants_nfn',
db.Column('plants_id', db.ForeignKey('plants.id'), nullable=False),
db.Column('nfn_id', db.ForeignKey('nfn.id'), nullable=False),
db.UniqueConstraint('plants_id', 'nfn_id'),
)
修改植物模型并设置两者之间的关系后,请记住 .dna 和 .nfn 属性将具有列表类型。您可以通过 append
ing 到列表来添加与实例的关系。
我强烈建议您使用 FlaskForm.populate_obj:
@app.route("/plants/new/", methods=['GET', 'POST'])
@login_required# User must be logged in to create a new plant
def new_plant():
obj = Plants()
form = NewPlantForm()
if form.validate_on_submit():
form.populate_obj(obj)
print(obj) # debugging
db.session.add(obj)
db.session.commit()
flash('Thank you ! You have successfully added '
'a plant to the database!', 'success')
return redirect(url_for('plants'))
image_file = url_for('static', filename='img/plants/default_plant_pic.jpg')
return render_template('new_plant.html', title='Add new plant',
image_file=image_file, form=form)
此外,您还可以通过添加几行代码来组合未来的工厂更新视图:
@app.route('/plant/<id>/edit', methods=('GET', 'POST',))
@app.route('/plant/new', methods=('GET', 'POST'))
def create_plant(id=None):
if id is not None:
obj = Plant.query.get(id)
else:
obj = Plant()
form = PlantForm(request.form, obj=obj)
if form.validate_on_submit():
form.populate_obj(obj)
db.session.add(obj)
db.session.commit()
flash('Thank you ! You have successfully added '
'a plant to the database!', 'success')
return redirect(url_for('get_plant', id=obj.id))
else:
image_file = url_for(
'static',
filename='img/plants/default_plant_pic.jpg')
return render_template('plant.html', title='Add new plant',
image_file=image_file,
form=form, obj=obj)
我对 Flask 和 SQLAlchemy 以及编码都是新手,所以请耐心等待。
我想做的是通过表单将数据发送到我的数据库。
工作正常,直到我想要另外两个具有一对多关系的 table,因为在 植物中可以积累许多元素并且植物可以具有许多属性 并且烧瓶抛出错误 AttributeError: 'list' 对象没有属性 '_sa_instance_state'.
形式是:
from flask_wtf import FlaskForm
from wtforms.ext.sqlalchemy.fields import QuerySelectMultipleField
from wtforms import StringField, PasswordField, SubmitField,BooleanField, TextAreaField
#Query for Dynamic Nutrient Accumulator Model
def enabled_dna():
return DNA.query.all()
#Query for Nitrogen Fixers Nursing Model
def enabled_nfn():
return NFN.query.all()
class NewPlantForm(FlaskForm):
common_name = StringField('Common Name', render_kw={"placeholder": "Common name"},
validators=[DataRequired(), Length(min=2, max=40)])
botanical_name = StringField('Botanical Name', render_kw={"placeholder": "Botanical name"},
validators=[DataRequired(), Length(min=2, max=80)])
short_description = TextAreaField('Short Description', render_kw={"placeholder": "Please add a short description"},
validators=[DataRequired()])
medicinal = TextAreaField('Medicinal Use', render_kw={"placeholder": "Medicinal use"},
validators=[DataRequired()])
dna = QuerySelectMultipleField('Select Element',query_factory=enabled_dna,allow_blank=True)
nfn = QuerySelectMultipleField('Select Property',query_factory=enabled_nfn,allow_blank=True)
submit = SubmitField('Add plant')
models.py 看起来像这样:
#Plants Table
class Plants(db.Model):
id = db.Column(db.Integer, primary_key=True)
common_name = db.Column(db.String(40), nullable=False)
botanical_name = db.Column(db.String(80), unique=True, nullable=False)
short_description = db.Column(db.Text, nullable=False)
medicinal = db.Column(db.Text, nullable=False)
image_file = db.Column(db.String(20), default='default_plant_pic.jpg')
date_added = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
dna_id = db.Column(db.Integer, db.ForeignKey('DNA.id'))
dna = db.relationship('DNA', backref=db.backref('plant_dna', lazy='dynamic')) # Dynamic_Nutrient_Accumulated
nfn_id = db.Column(db.Integer, db.ForeignKey('NFN.id'))
nfn = db.relationship('NFN', backref=db.backref('plant_nfn', lazy='dynamic')) # Nitrogen_Fixers_Nursing
def __repr__(self):
return f"Plants('{self.common_name}', '{self.botanical_name}', '{self.short_description}'," \
f" '{self.medicinal}', '{self.dna}', '{self.nfn}' )"
#Dynamic_Nutrient_Accumulated
class DNA(db.Model):
id = db.Column(db.Integer, primary_key=True)
element = db.Column(db.String(15))
def __repr__(self):
return '[ {}]'.format(self.element)
#Nitrogen_Fixers_Nursing
class NFN(db.Model):
id = db.Column(db.Integer, primary_key=True)
plant_extra = db.Column(db.String(40))
def __repr__(self):
return '[ {}]'.format(self.plant_extra)
路由和表单与仅包含一个字段的表单一起工作正常table。但是,当我添加包含来自其他 tables(form.dna.data 和 form.nfn.data)的数据的第二个和第三个字段时,它现在不起作用。
我的新工厂路线是:
@app.route("/plants/new/", methods=['GET', 'POST'])
@login_required# User must be logged in to create a new plant
def new_plant():
form = NewPlantForm()
if form.validate_on_submit():
new_plant = Plants(common_name=form.common_name.data,
botanical_name=form.botanical_name.data,
short_description=form.short_description.data,
medicinal=form.medicinal.data,
dna=form.dna.data,
nfn=form.nfn.data,
author=current_user)
db.session.add(new_plant)
db.session.commit()
flash('Thank you ! You have successfully added a plant '
'to the database!', 'success')
return redirect(url_for('plants'))
image_file = url_for('static', filename='img/plants/default_plant_pic.jpg')
return render_template('new_plant.html', title='Add new plant',
image_file=image_file, form=form)
渲染植物信息的路径是:
@app.route("/plants")
def plants():
plants = Plants.query.all()
return render_template('plants.html', title= 'Plants Database', plants=plants)
我已经尝试从终端在本地使用它并且它有效,但我不知道我遗漏了什么或者关系模型是否错误以使其从 Flask 应用程序运行。
在此先感谢您的耐心等待和帮助。
更新
经过反复试验,现在似乎一切正常(将具有 selected 字段的植物添加到数据库,将植物数据正确渲染到模板中,植物被正确添加到在我将 QuerySelectMultipleField 更改为 QuerySelectField 之后,使用 SQLite 的数据库浏览器查看数据库)。但是,我的意思是能够 select 并呈现多个选择。
我注意到的另一件事是,当使用 QuerySelectField 时,模板会正确呈现下拉列表,但是当尝试使用 QuerySelectMultipleField,它只呈现一个包含元素的列表,没有下拉列表。
这是模板的一小部分 select 字段 form.dna 和 form.nfn:
<div class="form-group">
{{ form.dna(class="form-control form-control-sm") }}
</div>
<div class="form-group">
{{ form.nfn(class="form-control form-control-sm")}}
</div>
我正在使用 Bootstrap。这件事可能与为多个 select 编写的模板格式不正确有关吗? 谢谢。
更新2
我设法让 QuerySelectMultipleField 通过像这样遍历表单数据来工作:
@app.route("/plants/new/", methods=['GET', 'POST'])
@login_required# User must be logged in to create a new plant
def new_plant():
form = NewPlantForm()
if form.validate_on_submit():
new_plant = Plants(common_name = form.common_name.data, botanical_name = form.botanical_name.data,
short_description = form.short_description.data, medicinal=form.medicinal.data,
author=current_user)
**for dna_element in form.dna.data:
new_plant.dna = dna_element
for nfn_element in form.nfn.data:
new_plant.nfn = nfn_element**
db.session.add(new_plant)
db.session.commit()
flash(f'Thank you ! You have successfully added a plant to the database!', 'success')
return redirect(url_for('plants'))
image_file = url_for('static', filename='img/plants/default_plant_pic.jpg')
return render_template('new_plant.html', title='Add new plant',
image_file=image_file, form=form)
我不再收到错误 AttributeError: 'list' object has no attribute '_sa_instance_state' 并且植物已成功添加到数据库中,但是当我查看数据库时,我可以看到只有一个选项是 selected,而不是多个选项。 根据我在这里阅读的内容: Flask App Using WTForms with SelectMultipleField ,我应该使用 form.something.data 来获取我所做的项目列表,但仍然不起作用我只得到一件物品。 请帮忙。 谢谢!
更新 3 并解决问题
执行 sleblanc 的 响应后,我现在有以下代码可以与表单一起使用并正确显示: **models.py : **
plants_dna_table = db.Table(
'plants_dna',
db.Column('plants_id', db.Integer, db.ForeignKey('plants.id'), nullable=False),
db.Column('dna_id', db.Integer, db.ForeignKey('DNA.id'), nullable=False),
db.UniqueConstraint('plants_id', 'dna_id'))
plants_nfn_table = db.Table(
'plants_nfn',
db.Column('plants_id', db.Integer, db.ForeignKey('plants.id'), nullable=False),
db.Column('nfn_id', db.Integer, db.ForeignKey('NFN.id'), nullable=False),
db.UniqueConstraint('plants_id', 'nfn_id'))
#Plants Table
class Plants(db.Model):
id = db.Column(db.Integer, primary_key=True)
common_name = db.Column(db.String(40), nullable=False)
botanical_name = db.Column(db.String(80), unique=True, nullable=False)
short_description = db.Column(db.Text, nullable=False)
medicinal = db.Column(db.Text, nullable=False)
image_file = db.Column(db.String(20), default='default_plant_pic.jpg')
date_added = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
dna = db.relationship('DNA', secondary = plants_dna_table) # Dynamic_Nutrient_Accumulated
nfn = db.relationship('NFN', secondary = plants_nfn_table) # Nitrogen_Fixers_Nursing
def __repr__(self):
return f"Plants('{self.common_name}', '{self.botanical_name}', '{self.short_description}'," \
f" '{self.medicinal}', '{self.dna}', '{self.nfn}' )"
#Dynamic_Nutrient_Accumulated
class DNA(db.Model):
id = db.Column(db.Integer, primary_key=True)
element = db.Column(db.String(15))
def __repr__(self):
return '{}'.format(self.element)
#Nitrogen_Fixers_Nursing
class NFN(db.Model):
id = db.Column(db.Integer, primary_key=True)
plant_extra = db.Column(db.String(40))
def __repr__(self):
return '{}'.format(self.plant_extra)
用大写字母显示的 db.ForeignKey('DNA.id') 完成了工作,不会出现找不到 table 的错误DNA.
**routes.py : **
#Route for users to add a plant to the database
@app.route("/plants/new/", methods=['GET', 'POST'])
@login_required# User must be logged in to create a new plant
def new_plant():
form = NewPlantForm()
if form.validate_on_submit():
new_plant = Plants(common_name = form.common_name.data, botanical_name = form.botanical_name.data,
short_description = form.short_description.data, medicinal=form.medicinal.data,
author=current_user)
for dna_element in form.dna.data:
new_plant.dna.append(dna_element)
for nfn_element in form.nfn.data:
new_plant.nfn.append(nfn_element)
print(new_plant)
db.session.add(new_plant)
db.session.commit()
flash(f'Thank you ! You have successfully added a plant to the database!', 'success')
return redirect(url_for('plants'))
image_file = url_for('static', filename='img/plants/default_plant_pic.jpg')
return render_template('new_plant.html', title='Add new plant',
image_file=image_file, form=form)
谢谢@sleblanc!
您已经建立了相反的关系模型。
如果我没记错的话,你的植物与你的 DNA 和 NFN 之间存在一对多关系,这意味着一个 'Plants' 对象将具有多个 DNA 和多个 NFN。根据定义,您的 'Plants' 模型只有一个 DNA 字段和一个 NFN 字段,这意味着无法将关联存储在数据库中。
您将需要修改您的 Plants 模型以表示该关系。您必须首先确定 'DNA' 或 'NFN' 是否可以由多个 'Plants' 共享,或者它们是否对于每个 'Plants' 实例都是唯一的,因为它涉及不同的模式。
class Plants(db.Model):
id = db.Column(db.Integer, primary_key=True)
...
# second option, exclusive relationship
class DNA(db.Model):
id = db.Column(db.Integer, primary_key=True)
...
plants_id = db.Column(db.ForeignKey(Plants.id), nullable=False)
...
class NFN(db.Model):
id = db.Column(db.Integer, primary_key=True)
...
plants_id = db.Column(db.ForeignKey(Plants.id), nullable=False)
...
# first option, non-exclusive relationship
class Plants(db.Model):
...
dna = relationship("DNA", secondary=plants_dna_table)
nfn = relationship("NFN", secondary=plants_nfn_table)
plants_dna_table = db.Table(
'plants_dna',
db.Column('plants_id', db.ForeignKey('plants.id'), nullable=False),
db.Column('dna_id', db.ForeignKey('dna.id'), nullable=False),
db.UniqueConstraint('plants_id', 'dna_id'),
)
plants_nfn_table = db.Table(
'plants_nfn',
db.Column('plants_id', db.ForeignKey('plants.id'), nullable=False),
db.Column('nfn_id', db.ForeignKey('nfn.id'), nullable=False),
db.UniqueConstraint('plants_id', 'nfn_id'),
)
修改植物模型并设置两者之间的关系后,请记住 .dna 和 .nfn 属性将具有列表类型。您可以通过 append
ing 到列表来添加与实例的关系。
我强烈建议您使用 FlaskForm.populate_obj:
@app.route("/plants/new/", methods=['GET', 'POST'])
@login_required# User must be logged in to create a new plant
def new_plant():
obj = Plants()
form = NewPlantForm()
if form.validate_on_submit():
form.populate_obj(obj)
print(obj) # debugging
db.session.add(obj)
db.session.commit()
flash('Thank you ! You have successfully added '
'a plant to the database!', 'success')
return redirect(url_for('plants'))
image_file = url_for('static', filename='img/plants/default_plant_pic.jpg')
return render_template('new_plant.html', title='Add new plant',
image_file=image_file, form=form)
此外,您还可以通过添加几行代码来组合未来的工厂更新视图:
@app.route('/plant/<id>/edit', methods=('GET', 'POST',))
@app.route('/plant/new', methods=('GET', 'POST'))
def create_plant(id=None):
if id is not None:
obj = Plant.query.get(id)
else:
obj = Plant()
form = PlantForm(request.form, obj=obj)
if form.validate_on_submit():
form.populate_obj(obj)
db.session.add(obj)
db.session.commit()
flash('Thank you ! You have successfully added '
'a plant to the database!', 'success')
return redirect(url_for('get_plant', id=obj.id))
else:
image_file = url_for(
'static',
filename='img/plants/default_plant_pic.jpg')
return render_template('plant.html', title='Add new plant',
image_file=image_file,
form=form, obj=obj)