Django - get table data from templates into views.py - django

I am making a restaurant application and currently working on takeaway food functionality i.e. user orders food online.
I am displaying food items from my postgresql database onto my takeaway.html template and assigning each food item a class. Each food item will have an 'add to basket' button, JavaScript provides all functionality related to the basket.
I have found some resources that mention using the GET method with a form but I'm still not too sure. I am curious as to how I can access this 'basket' in my views.py and be able to put the values into my database.
I wish to access the food name, quantity and the price from the table if possible. Any resources or help would be greatly appreciated.
takeaway.html
<div class="col-sm-12 my-auto">
<h3>Starters</h3>
{% for starter in starters %}
<div id="{{ starter.id }}">
<span class="food-item-name">{{ starter.name }}</span>
<div class="food-item-details">
<p>{{ starter.description }}</p>
<p class="food-item-price">{{ starter.price }}</p>
<p>{% for a in starter.allergen.all %}{{ a.name }} | {% endfor %}</p>
<button class="add-item-button" onclick="addToBasket(this)">Add to Basket</button>
</div>
{% endfor %}
</div>
<div>
<h3>Mains</h3>
{% for m in mains %}
<div id="{{ m.id }}">
<span class="food-item-name">{{ m.name }}</span>
<div class="food-item-details">
<p>{{ m.description }}</p>
<p class="food-item-price">{{ m.price }}</p>
<p>{% for a in m.allergen.all %}{{ a.name }} | {% endfor %}</p>
<button class="add-item-button" onclick="addToBasket(this)">Add to Basket</button>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
<div>
<h3>Basket</h3>
<form method="get">
<table id="basket" style="border: 1px solid black">
<tr>
<th>Item</th>
<th>Quantity</th>
<th>Price</th>
<th>Total Price of Item(s)</th>
</tr>
</table>
<h3 id="basket-total-price">0.0</h3>
<button type="submit">submit</button>
</form>
</div>
takeaway.js
function addToBasket(selected)
{
const id = selected.parentElement.parentElement;
const itemName = id.getElementsByClassName("food-item-name")[0].innerText;
const itemPrice = id.getElementsByClassName("food-item-price")[0].innerText;
// check if item already in basket
if (check(itemName))
{
updateQuantity(itemName);
updateItemPrice(itemName);
}
else
{
const basketTable = document.getElementById("basket");
const rowCount = basketTable.rows.length;
const row = basketTable.insertRow(rowCount);
const basketRowName = row.insertCell(0);
const basketRowQuantity = row.insertCell(1);
const basketRowPrice = row.insertCell(2)
const basketRowTotalPrice = row.insertCell(3);
basketRowName.className = "basket-item-name";
basketRowQuantity.className = "basket-item-quantity";
basketRowPrice.className = "basket-item-price";
basketRowTotalPrice.className = "basket-item-total-price";
basketRowName.innerText = itemName;
basketRowPrice.innerText = itemPrice;
basketRowQuantity.innerText = "1";
updateItemPrice(itemName);
}
}
// check if item already in basket
function check(itemName)
{
const basketTable = document.getElementById("basket");
for(let i = 0; i < basketTable.rows.length; i++)
{
if (basketTable.rows[i].cells[0].innerHTML === itemName)
{
return true;
}
}
}
// update quantity field for item
function updateQuantity(itemName)
{
const basketTable = document.getElementById("basket");
for(let i = 0; i < basketTable.rows.length; i++)
{
if (basketTable.rows[i].cells[0].innerHTML === itemName){
const itemQuantity = basketTable.rows[i].getElementsByClassName("basket-item-quantity")[0];
let quantity = Number(itemQuantity.innerText);
quantity += 1;
itemQuantity.innerText = quantity;
}
}
}
// update price for item and total basket
function updateItemPrice(itemName)
{
const basketTable = document.getElementById("basket");
let itemTotal = 0;
let basketTotal = 0;
for (let i = 0; i < basketTable.rows.length; i++)
{
if (basketTable.rows[i].cells[0].innerHTML === itemName)
{
let itemPrice = basketTable.rows[i].getElementsByClassName("basket-item-price")[0];
let itemQuantity = basketTable.rows[i].getElementsByClassName("basket-item-quantity")[0];
let itemPriceTotal = basketTable.rows[i].getElementsByClassName("basket-item-total-price")[0];
let overall = document.getElementById("basket-total-price");
let current_price = parseFloat(overall.innerText);
// update price for items x quantity
itemTotal = parseFloat(itemPrice.innerText) * parseInt(itemQuantity.innerText);
itemPriceTotal.innerText = ""+ itemTotal;
// update basket total price
basketTotal = current_price + itemTotal;
overall.innerHTML = ""+basketTotal
}
}
}

Related

Could not parse some characters: video.viewers.all.count| ans video.viewers_by_ip.all.count||intcomma

How I can parse or sum two ManyToMany field in the template
<div class=""> <h6 class="card-text ml-2 p-2 bd-highlight" style="text-align: left; height: 1px; "><small class="text-muted ">{{ video.viewers.all.count + video.viewers_by_ip.all.count|intcomma }} views . </small></h6></div>
I tried to get this number by my view but I got this message
'list' object has no attribute 'viewers_by_ip'
my view
profile = get_object_or_404(Account, username=request.user)
if not profile.is_active:
return render(request, 'personal/violated.html')
users = [user for user in profile.following.all()]
video = []
for u in users:
p = Account.objects.get(username=u)
p_posts = p.video_set.all()
video.append(p_posts)
my_post = profile.account_video()
video.append(my_post)
if len(video):
video = sorted(chain(*video), reverse=True, key=lambda video: video.created_date)
video_viewers_ip = video.viewers_by_ip.all()
video_viewers = video.viewers.all()
video_views = len(list(chain(video_viewers_ip, video_viewers)))

How to insert selected items to db in django?

Here is my Template :
{% for pr in productlist %}
<ul>
<li><input type="checkbox" name="mylistch" value="{{ pr.productid }}"></li>
<li><input type="hidden" name="mylist" value="{{ pr.productname }}"></li>
<li><input type="number" name="mylist" id="prqty"/></li>
</ul>
{% endfor %}
and View :
pch = request.POST.getlist('mylistch')
pnch = iter(pch)
pr = request.POST.getlist('mylist')
pri = iter(pr)
for pid, pname, ptotal in zip(pnch , pri , pri):
models.Sellinvoiceitems.objects.create(
productid=pid
productname=pname,
totalnumber=ptotal,
sellinvoice = invoice,
stockid = stock
)
Here i checked 5 checkbox with this ids : 6 , 9 , 10 , 12 , 19, But ids : 1 , 2 , 3 ,4 ,5 inserted to db, what is problem here?

How to get the ID of record in another html?

why i cant get the ID of payment type, even i already print the ID in the html?
in my first html (elementary.html) I have this code
<select name="gradelevel" id="gradelevel" onchange="ChangeYearList(this.value)">
<option">-- Education Level --</option>
{% for ylvl in edulevel %}
<option value="{{ylvl.id}}">{{ylvl.Description}}</option>
{% endfor %}
</select>
<div id="txtHint" class="scale-in-center" width="100%"></div>
<script>
function ChangeYearList(str) {
var xhttp;
var x = document.getElementById("gradelevel").value;
if (str == "") {
document.getElementById("txtHint").innerHTML = "";
document.getElementById("demo").innerHTML = x;
return;
}
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xhttp.open("GET", "{% url 'paymentElementary' %}?payments_ID="+str, true);
xhttp.send();
}
</script>
this is my views.py
def paymentElementary(request):
paymentsid = request.GET.get('payments_ID')
payment = ScheduleOfPayment.objects.filter(Education_Levels=paymentsid).order_by('Payment_Type').distinct('Payment_Type')
return render(request, 'accounts/paymentElementary.html', {"payment":payment})
This is my second html (paymentElementary.html)
<select id="payments" name ="payments">
<option value="0">-- Payment Type --</option>
{% for paymentschedule in payment %}
<option value="{{paymentschedule.Payment_Type.id}}">{{paymentschedule.Payment_Type.id}}. {{paymentschedule.Payment_Type}}</option>
{% endfor%}
</select>
this is what it looks like in web view
it works like a charm. but when i tried to save it into my database
id = request.POST.get('payments')
payment = PaymentType(id=id)
V_insert_data = StudentsEnrollmentRecord.objects.create(
Payment_Type=payment
)
this is the error
this is the full traceback
update view.py file in this way
def paymentElementary(request):
paymentsid = request.GET.get('payments_ID')
payment = ScheduleOfPayment.objects.get(Education_Levels=paymentsid).order_by('Payment_Type').distinct('Payment_Type')
return render(request, 'accounts/paymentElementary.html', {"payment":payment})

Request.files 400 Bad Request in flask

flask with a project in my project I'm uploading an application I'm developing. I have 2 image upload areas. I don't have any trouble when I load 2. 400 Bad Request: KeyError: I get an error in the 'gelinFoto' style when I upload an image or when I push the send button when I never load it. Where am I making a mistake?
def admin():
form = KisiForm(request.form)
if request.method == "POST":
gelinFoto = request.files['gelinFoto']
damatFoto = request.files['damatFoto']
if gelinFoto or damatFoto:
yol = app.config['UPLOAD_FOLDER'] + whuser
yol = yol + '/profil'
gfilename = secure_filename(gelinFoto.filename)
dfilename = secure_filename(damatFoto.filename)
gelinFoto.save(os.path.join(yol, gfilename))
damatFoto.save(os.path.join(yol, dfilename))
kisi = bilgi(gelinFoto = gfilename, damatFoto = dfilename)
db.session.add(kisi)
db.session.commit()
return redirect(url_for("admin"))
return render_template("admin/index.html",form=form)
Html
<form method="post" enctype="multipart/form-data" class="col-12">
<div class="form-group">
<label for="exampleFormControlFile1">Gelinin Fotoğrafı : </label>
<div class="upload">
<img src="{{ url_for('static', filename='admin/images/upload.png') }}" class="uploadImage" alt="">{{ render_field(form.gelinFoto,id="gelinFoto",class="gdfoto",accept=".png,.jpg,.jpeg") }} </div>
<small id="emailHelp" class="form-text text-muted">Gelinin fotoğrafını yükleyiniz.</small>
</div>
<div class="form-group">
<label for="exampleFormControlFile1">Damatın Fotoğrafı : </label>
<div class="upload"><img src="{{ url_for('static', filename='admin/images/upload.png') }}" class="uploadImage" alt="">{{ render_field(form.damatFoto,id="damatFoto",class="gdfoto",accept=".png,.jpg,.jpeg") }}
</div>
<small id="emailHelp" class="form-text text-muted">Damatın fotoğrafını yükleyiniz.</small>
In your view you have both
gelinFoto = request.files['gelinFoto']
damatFoto = request.files['damatFoto']
This is why you get that error
When the file is not provided, then there is no request.files['gelinFoto'] for example, and Python tries to look it up, but it can't cause there is no key named gelinFoto!
The simplest trick is defining theme like this:
gelinFoto = request.files.get('gelinFoto', None)
damatFoto = request.files.get('damatFoto', None)
This way it uses an inline condition to get the keys, if they are not provided, then it sets the value None
Later in your code I see you did that again,
if gelinFoto or damatFoto:
# ... Your other coders
gfilename = secure_filename(gelinFoto.filename)
dfilename = secure_filename(damatFoto.filename)
gelinFoto.save(os.path.join(yol, gfilename))
damatFoto.save(os.path.join(yol, dfilename))
It's wrong, you are checking with it with or and then u except both to be not None !!
It's better to do the operation for each one separately, like:
if gelinFoto:
yol = app.config['UPLOAD_FOLDER'] + whuser
yol = yol + '/profil'
gfilename = secure_filename(gelinFoto.filename)
gelinFoto.save(os.path.join(yol, gfilename)
if damatFoto:
yol = app.config['UPLOAD_FOLDER'] + whuser
yol = yol + '/profil'
dfilename = secure_filename(damatFoto.filename)
damatFoto.save(os.path.join(yol, dfilename)
# I'm not sure if there is a better way to do this but about kisi line This is the best that came up to me ( ofcourse there are better ways )
if gelinFoto and damatFoto:
kisi = bilgi(gelinFoto = gfilename, damatFoto = dfilename)
elif gelinFoto:
kisi = bilgi(gelinFoto = gfilename)
elif damatFoto:
kisi = bilgi(damatFoto = dfilename)

How to update a specific value inside a dictionary using JQuery and Flask?

I've created a session list that contains my products, i need to update the quantity of any product by increasing it amount, for that am using an HTML type="number" , i also created a function which take the changed amount and multiplying it value with the current quantity, so lets say the amount of the first product by default is 2 by increasing the number lets say 2 the product amount will become 4 and so on, also the price will be multiplied .
Here are the codes:
<th style="text-align: center;" class="amount-izd">{{value["amount"]}}</th>
<th style="text-align: center; width: 14%;">
<div class="block">
<input type="number" id="myNumber" value="1" min=1 data-amount='{{value["amount"]}}' data-pros='{{value["id"]}}' data-price='
{% if g.currency == "euro" %}
{{format_price(value["price"] * config.SITE_CURRENCIES["euro"]).rsplit(".",1)[0]}}
{% elif g.currency == "dollar" %}
{{format_price(value["price"] * config.SITE_CURRENCIES["dollar"]).rsplit(".",1)[0]}}
{% else %}
{{format_price(value["price"] * config.SITE_CURRENCIES["ruble"]).rsplit(".",1)[0]}}
{% endif %}
'>
<label for="myNumber">qty</label>
</div>
</th>
JQuery codes:
$("input[type='number']").bind('keyup change click', function (e) {
if (! $(this).data("previousValue") ||
$(this).data("previousValue") != $(this).val()
)
{
var currentAmount = $(this).attr('data-amount');
var currentPrice = $(this).attr('data-price');
$(this).closest('tr').find('.amount-izd').text(parseInt(currentAmount) * $(this).val());
$(this).closest('tr').find('.price-izd').text(parseInt(currentPrice) * $(this).val());
$.ajax({
type: 'post',
url: '/standard-{{g.currency}}/profile/'+$(this).attr("data-pros")+'/update/price/' + parseInt(currentPrice) * $(this).val(),
cache: false
}).done(function(data){
if(data.error){
toastr.error(data.error)
}
});
$(this).data("previousValue", $(this).val());
} else {
}
});
And finally views.py :
#profile_route.route("/standard-<set_curr>/profile/cart/", methods=['GET','POST'])
#authorize
def cart_products():
if "cart" not in session:
return render_template("my-cart.html", display_cart = {}, total = 0)
else:
items = session["cart"]
dict_of_products = {}
total_price = 0
for item in items:
product = Goods.query.get(item)
total_price += product.price
if product.id in dict_of_products:
pass
else:
dict_of_products[product.id] = {"qty":1, "name":product.product_name, 'category':product.Category.name, "sizes": product.sizes, "hex_color":product.hex_color, "text_color":product.text_color, "material":product.material, "article":product.article, "price":product.price, "sort": product.sort, "amount": product.amount, 'slug':product.slug, 'public_id' : product.public_id, "id":product.id}
return render_template("my-cart.html", display_cart=dict_of_products, total = total_price)
#profile_route.route("/standard-<set_curr>/profile/<int:id>/update/price/<price>", methods=['GET','POST'])
#login_required
def update_price(id, price):
items = session["cart"]
dict_of_products = {}
for item in items:
product = Goods.query.get(item)
if product.id in dict_of_products:
dict_of_products[id]['price'] = price
return jsonify(success=dict_of_products[id]['price'])
return jsonify(error='No product found.')
If i changed the amount , in console i got a 500 error that says:
return jsonify(success=dict_of_products[id]['price'])
KeyError: 47
Please how to overcome this problem ?
Update:
I was wondering , is it possible to update any value of the dictionary by accessing it directly from JQuery ??