Getting data from the session[] Python, Flask - python

I'm trying to make simple cart system to the online shop using Python and framework - Flask.
I'm getting data from form in products.html then writing it into the session. I have a problem with getting this data and returning it to the cart.html - I'm get just clear page instead of names of the products i added to the cart.
products.html
{% for el in products %}
<p>Name {{ el.product_name }}</p>
<p>Description {{ el.product_description }}</p>
<p>Image </p> <img width="200" height="200" src="data:;base64,{{ el.product_img }}">
<p>Cost: {{ el.product_cost }} тенге.</p>
<form method="post" action="/cart">
<input type="hidden" name="cart_prod_name" value="{{ el.product_name }}">
<input type="submit" value="Add to cart">
</form>
{% endfor %}
Python function cart():
#app.route('/cart', methods=['POST', 'GET'])
def cart():
if 'cart' not in session:
session['cart'] = []
if request.method == 'POST':
cart_prod_name = request.form['cart_prod_name']
session['cart'] += cart_prod_name
return redirect('/cart')
if request.method == 'GET':
cart_products = session['cart']
return render_template('cart.html', cart_products=cart_products)
cart.html:
{% for cart_product in cart_products %}
<p>{{ cart_product.order_prod_name }}</p>
{% endfor %}

From flask.session docs:
Be advised that modifications on mutable structures are not picked up
automatically, in that situation you have to explicitly set the
attribute to True yourself.
your carts holder object is a mutable structure == list so you have to set after changes
session.modified = True

I sloved that problem. Exactly I needed to iterate cart_product in cart_roducts and output cart_product and don't call it to output order_prod_name.
Fixed cart.html:
{% for cart_product in cart_products %}
<p>{{ cart_product }}</p>
{% endfor %}

Related

Django getting right return value for post.request

I am trying to get the product id using request.post in Django. I am currently testing using the console, but the only product_id value I am returned is 1.
This is the particular function in the view:
def test_view(request):
cart_obj, new_obj = Cart.objects.new_or_get(request)
my_carts_current_entries = Entry.objects.filter(cart=cart_obj)
products = Product.objects.all()
if request.POST:
product_id = request.POST.get('product_id')
entry_quantity = request.POST.get('entry_quantity')
product_obj = Product.objects.get(id=product_id)
print(product_id)
# print(entry_quantity)
# Entry.objects.create(cart=cart_obj, product=product_obj, quantity=product_quantity)
return render(request, 'carts/test.html', {'cart_obj': cart_obj, 'my_carts_current_entries': my_carts_current_entries,
'products': products})
This is the html on the template.
<form method="POST">
<br>
{% csrf_token %}
{% for product in products %}
{{ product.name }} <br>
<button>Add to Basket</button>
{{ product.id }}
<input type="hidden" name='product_id' value='{{ product.id }}'>
<br>
{% endfor %}
</form>
Your problem is that you have as many <input> tags within 1 <form> as many products you have displayed. They all have the same name, so you always get the value of the first one.
I'd recommend getting rid of <input> and attaching the value of product.id to the button itself (or <input type="submit"> to be exact). Here's the more descriptive explanation:
How can I build multiple submit buttons django form?
An alternative would be to change your code to have multiple forms, like that:
{% for product in products %}
<form method="POST">
{% csrf_token %}
{{ product.name }}
<br/>
<button>Add to Basket</button>
{{ product.id }}
<input type="hidden" name='product_id' value='{{ product.id }}'>
</form>
<br/>
{% endfor %}

Issue with many-to-many relationship in Flask-SQLAlchemy

I've a strange problem with adding many-to-many relation in Flask app.Everything seems to be ok because when I use the code below in "Python Console" (PeCharm) I see a new relation in my database.
f = CAR.query.filter_by(ID_CAR=1).first()
m = MANAGER.query.filter_by(ID_MANAGER=1).first()
f.CAR_MENAGO.append(m)
db.session.commit()
but when I want to do it in Flask app using WTForms, nothing happen, I don't get any error even. Do You know what should I add to this code below ?
#app.route('/test1',methods=['GET', 'POST'])
#login_required
def test1():
form = test()
id_car = form.ID_CAR.data
f = CAR.query.filter_by(ID_CAR=id_car).first()
m = MANAGER.query.filter_by(ID_MANAGER=1).first()
if form.validate_on_submit():
f.CAR_MENAGO.append(m)
db.session.commit()
return render_template('test1.html',form=form)
return render_template('test1.html',form=form)
Template code:
{% extends "dashboardmanager.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block content %}
<div class="container">
<form class="form-signin" method="post" action="/test1">
{{message}}
{{ form.hidden_tag() }}
{{ wtf.form_field(form.ID_CAR) }}
<button class="btn btn-success btn-xsy" type="submit">Submit</button>
</form>
</div>
{% endblock %}

posting Flask wtforms in loop and saving data

I have a Flask-WTF form fields in for loop. I want to post the new quantities for each item.
I am reading about field list. I still dont understand but i think they might be the answer.
#app.route('/checkout')
def checkout():
form = CartForm()
for item in current_user.cart:
product = Product.query.get(item.product_id)
cart_items.append({product: item.quantity})
return render_template('checkout.html',cart_items=cart_items,form=form)
{% for item in cart_items %}
{% for product, quantity in item.items() %}
{{product.name}}
{{product.price}}
{{form.quantity }}
{% endfor %}
{% endfor %}
Problem1: When looping over each Each Flask-WTF form field has the same name.
The output
<select id="quantity" name="quantity"><option value="1">1</option></select>
<select id="quantity" name="quantity"><option value="1">1</option></select>
problem2: how save in the backed if each form has a different name.
I have the same problem exactly! But I solve it without Flask-WTF, the solution below was based on my app. I have an album edit page, I need to loop a text input for each picture in album, then save the text for each picture.
I loop the input in HTML, notice I set the action value for another view function and use each photo's id as each text input's name:
<form action="{{ url_for('edit_photo', id=album.id) }}" method="POST">
<ul>
{% for photo in photos %}
<li>
<img class="img-responsive portrait" src="{{ photo.path }}" alt="Some description"/>
<textarea name="{{ photo.id }}" placeholder="add some description" rows="3">{% if photo.description %}{{ photo.description }}{% endif %}</textarea>
</li>
{% endfor %}
</ul>
<hr>
<input class="btn btn-success" type="submit" name="submit" value="submit">
Then I loop the picture and save the input data (get it's value by it's id):
#app.route('/edit-photo/<int:id>', methods=['GET', 'POST'])
#login_required
def edit_photo(id):
album = Album.query.get_or_404(id)
photos = album.photos.order_by(Photo.order.asc())
if request.method == 'POST':
for photo in photos:
photo.about = request.form[str(photo.id)]
db.session.add(photo)
return redirect(url_for('.album', id=id))
return render_template('edit_photo.html', album=album, photos=photos)

Flask Select field - Not a valid choice

I have the following code in form.py
OPTIONS = ['Option1', 'Option2', 'Option3']
class Test_Form(Form):
test = SelectField('Dropdown', coerce= str,
choices=[(f, f) for f in OPTIONS])
submit = SubmitField('Submit')
And the following code in my template
<div class = "control-group">
<label class="control-label">
{{ form.test.label }} </label>
{% if form.test.errors %}
{% for error in form.test.errors %}
<p class="error-message"> {{ error }}</p>
{% endfor %}
{% endif %}
<div class="controls">
<select name=form.test.label width="80px">
{% for i,j in form.test.choices %}
<option value = {{ i }} > {{ j }} </option>
{% endfor %}
</select>
</div>
</div>
Following is my view function
def show_logs():
my_form = Test_Form()
if request.method == "POST":
if logs_form.validate() == False:
return render_template('test.html', form = my_form)
else:
return my_form.test.data
#return render_template('test_success.html', output = output_list)
elif request.method == "GET":
return render_template('test.html', form = my_form)
I get a "Not a Valid Choice" every time I submit the form. I went through the previous questions on SO and tried coerce = str but I still get the same message. What am I missing here?
I tried your code and it works perfectly on my end. The only thing I changed however was your template code as yours was incomplete. It had no submit button and no <form> tag declaration.
This is the template code that I used:
<form action="" method='post'>
{{ form.hidden_tag() }}
<ul class="request_form">
{%if form.errors%}
Please correct the following fields:
{%for each in form.errors%}
<br>{{each}}
{%endfor%}
{%endif%}
{%for each in form%}
{%if each.name != "csrf_token" and each.name!="submit"%}
<li>
<label>{{each.name}}</label>
{{each()}}
</li>
{%endif%}
{%endfor%}
<li/>{{form.submit}}
</ul>
</form>
Also, in your view, you're checking for logs_form.validate() when it should be my_form.validate()
I hope this solves your problem.

how to submit checklist in Django with GET

Hi I have on my html file this, tags and tagInfos are both queryset´s of Django, that 2 for´s are only to show wich one belongs to the other:
<form action="/chart/chart/" method="get">
{% if tags.count > 0 %}
{% for tag in tags %}
{% for tagInfo in tagInfos %}
{% if tag.taginfo_idtaginfo1_id == tagInfo.idtaginfo %}
<p>
<input type="checkbox" name="checks[]" value="{{ tag.idtag }}" />
</p>
{% endif %}
{% endfor %}
{% endfor %}
{% csrf_token %}
<button type="submit" class="btn btn-primary">Submit creation</button>
{% else %}
<p>None TAG to select.</p>
{% endif %}
</form>
So and on my view i try to do that:
def chart(request):
if 'checks' in request.GET and request.GET['checks']:
chosen = request.GET.getlist('checks')
return render_to_response('Chart/chart.html',{'chosen':chosen})
else:
return render_to_response('Chart/chart.html',{})
But don´t show any of the selected checkboxes on the other html, I´m using {{ chosen }} to show.
Any ideas of what I´m doing wrong?
try this:
def chart(request):
if 'checks[]' in request.GET: #<----- 'checks[]'
chosen = request.GET.getlist('checks[]') #<----- 'checks[]'
return render_to_response('Chart/chart.html',{'chosen':chosen})
else:
return render_to_response('Chart/chart.html',{})

Categories