Flask (j) db.session.add(obj) db.session.commit() flash('谢谢!您已成功添加' “数据库中的工厂!”,“成功”) 返回重定向(url_for('get_plant',id=obj.id)) 其他: image\u

Flask (j) db.session.add(obj) db.session.commit() flash('谢谢!您已成功添加' “数据库中的工厂!”,“成功”) 返回重定向(url_for('get_plant',id=obj.id)) 其他: image\u,flask,sqlalchemy,flask-sqlalchemy,flask-wtforms,Flask,Sqlalchemy,Flask Sqlalchemy,Flask Wtforms,(j) db.session.add(obj) db.session.commit() flash('谢谢!您已成功添加' “数据库中的工厂!”,“成功”) 返回重定向(url_for('get_plant',id=obj.id)) 其他: image\u file=url\u( “静态”, filename='img/plants/default\u plant\u pic.jpg') 返回渲染模板('plant.html',title='addnewplant', image\u file=

(j) db.session.add(obj) db.session.commit() flash('谢谢!您已成功添加' “数据库中的工厂!”,“成功”) 返回重定向(url_for('get_plant',id=obj.id)) 其他: image\u file=url\u( “静态”, filename='img/plants/default\u plant\u pic.jpg') 返回渲染模板('plant.html',title='addnewplant', image\u file=image\u file, 形式=形式,对象=对象)
不是100%确定,但我认为您需要去掉
中的
.all()
中的
已启用\u dna
已启用\u nfn
对于
查询选择多字段
,因为感谢您的回复,我也尝试过,但没有效果。我也读过关于这些关系的书,所以我写的模型要么是错误的,要么是路由逻辑,或者两者都是错误的,但在cmd中测试它们是有效的。不是100%确定,但我认为你需要去掉
.all()
已启用\u dna
已启用\u nfn
中,对于
查询选择多字段
,正如在感谢回复中一样,我也尝试过,但没有效果。我也读过关于关系的内容,所以我写的模型可能是错误的,或者路由逻辑是错误的,或者两者都是错误的,但是在cmd中测试它们是有效的。如果您是数据建模新手,那么这个答案中解释的概念叫做“关联表”,您好,sleblanc,谢谢您的帮助。我在想这些模型有问题。正如您所说,我使用了非排他关系,但是当尝试将plant.dna.append(元素)添加到db中时,我现在遇到了这个wierd错误:*\u state=attributes.instance\u state(instance)AttributeError:'InstrumentedList'对象没有属性'\u sa\u instance\u state';sqlalchemy.orm.exc.UnmappedInstanceError:类“sqlalchemy.orm.collections.InstrumentedList”未映射**我不确定这是否会解决所有问题,但请注意,您不能仅将表单值附加到.dna或.nfn关系,因为它们需要的是dna和nfn对象,而不是文本(表单)数据。在这个循环中,您可以查询数据库以获取DNA或NFN对象(如果它们已经存在),否则您将创建一个新实例并将其添加到会话中。sleblanc it works!天哪,终于起作用了。我已经在CMD上测试了它,并且在用户提交表单后它可以正常工作和显示。非常非常感谢!!!我现在知道如何在将来正确地实施它。上面的错误是因为我在做db.session.add(plant.dna),而不是db.session.add(plant)。但是,我在模型工厂上方添加了relationships表,并在其中添加了db.Integer。我以前尝试过表关系,但在其中实现了表DNA和NFN,而不是分开的。非常感谢。欢迎会话足够智能,可以在您添加“父”对象时添加依赖项,因此仅执行session.add(plant)不需要您也执行
session.add_all(plant.dna)。如果您不熟悉数据建模,那么本回答中解释的概念称为“关联表”。您好,sleblanc,谢谢您的帮助。我在想这些模型有问题。正如您所说,我使用了非排他关系,但是当尝试将plant.dna.append(元素)添加到db中时,我现在遇到了这个wierd错误:*\u state=attributes.instance\u state(instance)AttributeError:'InstrumentedList'对象没有属性'\u sa\u instance\u state';sqlalchemy.orm.exc.UnmappedInstanceError:类“sqlalchemy.orm.collections.InstrumentedList”未映射**我不确定这是否会解决所有问题,但请注意,您不能仅将表单值附加到.dna或.nfn关系,因为它们需要的是dna和nfn对象,而不是文本(表单)数据。在这个循环中,您可以查询数据库以获取DNA或NFN对象(如果它们已经存在),否则您将创建一个新实例并将其添加到会话中。sleblanc it works!天哪,终于起作用了。我已经在CMD上测试了它,并且在用户提交表单后它可以正常工作和显示。非常非常感谢!!!我现在知道如何在将来正确地实施它。上面的错误是因为我在做db.session.add(plant.dna),而不是db.session.add(plant)。但是,我在模型工厂上方添加了relationships表,并在其中添加了db.Integer。我以前尝试过表关系,但在其中实现了表DNA和NFN,而不是分开的。非常感谢。欢迎会话足够智能,可以在您添加“父”对象时添加依赖项,因此仅执行session.add(plant)不需要您也执行
session.add_all(plant.dna)
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')
#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)
@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)
<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>
 @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)
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)
#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)
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'),
    )
@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)