LAn
LAn

Reputation: 23

Getting specific input from a form used multiple times on one page

I'm trying to create a cart system using flask sql-alchemy. So far I've got three models although a lot of the data in these methods is useless.

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(30), unique=True, nullable=False)
    join_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow())
    password = db.Column(db.String(60), nullable=False)
    admin = db.Column(db.Boolean, nullable=False, default=False)
    messages = db.relationship('Message', backref='sender', lazy=True)
    cart = db.relationship('Cart', backref=db.backref('shopper', lazy=True, uselist=False))

class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    category = db.Column(db.String)
    title = db.Column(db.String)
    location = db.Column(db.String)
    price = db.Column(db.Integer)
    allocation = db.Column(db.Integer)
    ram = db.Column(db.Integer)
    storage = db.Column(db.Integer)
    players = db.Column(db.String)
    inCarts = db.relationship('Cart', secondary=association_table, backref=db.backref('cartItem', lazy='dynamic'))

class Cart(db.Model):
    id = db.Column(db.Integer, primary_key=True)    
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

I've got an addtocart form which is just a button,

class AddToCartForm(FlaskForm):
    submit = SubmitField('Order Now')

In my routes.py file I set the variable form=AddToCartForm() and check if it's valid on submit. I've got multiple items using this form so my problem is how would I check which item is being submitted.

This here is the html

<div class="server-option">
  <h5>{{ item.title }} [ {{ item.location }} ]</h5>
  <p style="display: inline; float: right;">Starting at ${{ item.price }} USD Monthly</p>
  <div class="server-specs">
  <p><small><span style="font-weight: bold;">CPU Allocation - </span>{{ item.allocation }}%</small></p>
  <p><small><span style="font-weight: bold;">RAM - </span>{{ item.ram }}GB</small></p>
  <p><small><span style="font-weight: bold;">Storage - </span> {{ item.storage }}GB {{ storage_type }}</small></p>
  <p><small><span style="font-weight: bold;">Players - </span>{{ item.players }}</small></p>
</div>
<form method="POST" action="">
  {{ form.hidden_tag() }}
  <div class="form-group">
    {{ form.submit(class="add-to-cart") }}
    <!-- ! Seperate item page for each item therefore you can use the link information to tell which item to add -->
  </div>
</form>
</div>

Upvotes: 0

Views: 142

Answers (1)

djnz
djnz

Reputation: 2050

Here's a few options depending on how your item page is currently setup:

  1. Add the item id field to the form (don't forget to add the field to your template):
    class AddToCartForm(FlaskForm):
        item_id = HiddenField()
        submit = SubmitField('Order Now')

and then use this in your POST handler to query the record by form['item_id'], for example. This approach may support having multiple forms on the same page, if you're rendering each form with the respective item Id.

  1. Similar to above, and if you're not using the id value on the page, you could preset the value of id after instantiating the form:
form = AddToCardForm()
form.item_id.data = myitem.id

return render_template(...)
  1. If each item is on it's own page, you could pass the Id into the form action:

View:

...
item_id = my_item.id
form = AddToCartForm()
return render_template('template.html', item_id=item_id, form=form)

Template:

...
<form action="{{url_for('your_post_view', id=item_id)}}" ... 

Finally, your POST handler view:

@app.route('/url/<id>')
def post_view(id):
    # Query using id etc.

Upvotes: 1

Related Questions