创建一个新对象将返回AttributeError:'list'对象没有属性'_sa_instance_state'

E R*_*uez 1 python flask flask-sqlalchemy

嗨,我正在尝试做一个简单的应用程序,使用户能够创建新的鸡尾酒。因此,我有两个具有多对多关系的模型

from . import db
assoc_table = db.Table('association',
   db.Column('ingredient_id', db.Integer, db.ForeignKey('ingredients.id')),
   db.Column('cocktail_id', db.Integer, db.ForeignKey('cocktails.id'))
)


class Ingredient(db.Model):

    __tablename__ = 'ingredients'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    cost_price = db.Column(db.Float, default=0.0)
    cocktails = db.relationship('Cocktail',
                                secondary=assoc_table,
                                backref=db.backref('ingredients'),
                                lazy='dynamic')


class Cocktail(db.Model):

    __tablename__ = 'cocktails'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), unique=True)
    serv_percentage = 0.25
    sell_price = db.Column(db.Float)
Run Code Online (Sandbox Code Playgroud)

在视图中,如果它是GET请求,则发送表单。如果是POST,我尝试创建Cocktail对象,然后将其保存在数据库中:

@main.route('/new', methods=['GET', 'POST'])
def new():
    form = CocktailForm()
    form.ingredients.choices = [(i.id, i.name) for i in Ingredient.query.all()]
    if form.validate_on_submit():
        cocktail_name = form.name.data
        cocktail_ingredients = Ingredient.query.filter(Ingredient.id.in_(form.ingredients.data)).all()
        c = Cocktail()
        c.name = form.name.data
        c.ingredients.append(cocktail_ingredients)
        db.session.add(c)
        db.session.commit()
        return redirect(url_for('.index'))
    return render_template('new.html', form=form)
Run Code Online (Sandbox Code Playgroud)

我得到AttributeError:

“列表”对象没有属性“ _sa_instance_state”

在试图创建一个空的行中 Cocktail:

c = Cocktail()
Run Code Online (Sandbox Code Playgroud)

我不知道这是什么问题。

我检查了很多答案,通常与关系有关,所以我真的不知道我的代码有什么问题

这是表单类,尽管我认为这不是问题:

class CocktailForm(Form):
    name = StringField('What is the coktail\'s name?', validators=[Required()])
    ingredients = SelectMultipleField('Ingredients', coerce=int)
    submit = SubmitField('Submit')
Run Code Online (Sandbox Code Playgroud)

谢谢

uni*_*rio 5

我认为您的错误实际上并非出自于c = Cocktail()行。

问题出在生产线上

c.ingredients.append(cocktail_ingredients)
Run Code Online (Sandbox Code Playgroud)

cocktail_ingredients是一个列表。c.ingredients当您只应将清单的实例附加Ingredient到时,便会将清单附加到。您想.extend改用:

c.ingredients.extend(cocktail_ingredients)
Run Code Online (Sandbox Code Playgroud)