3

Hi I am trying to do a simple application where users are capable of creating new cocktails. Therefore I have two models with a many2many relationship

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)

And in the view, I send the form if it is a GET request. If it's a POST, I try to create the Cocktail object and then save it on database:

@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)

I get AttributeError:

'list' object has no attribute '_sa_instance_state'

in the line that tries to create an empty Cocktail:

c = Cocktail()

I don't have a clue what is the problem.

I have checked many answers and usually is related to relationships so I don't really know what's wrong with my code

Here is the form class, although I think it's not the problem:

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

Thank you

1 Answer 1

15

I think your error isn't actually from the c = Cocktail() line.

The problem instead lies in the line

c.ingredients.append(cocktail_ingredients)

cocktail_ingredients is a list. You're appending a list to a c.ingredients, when you should only be appending instances of Ingredient to it. You want to use .extend instead:

c.ingredients.extend(cocktail_ingredients)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.