django template fetch ID or Name for selected dropdown value - django

I am building a new order form and there are few dropdowns on my HTML page. I would like to build a number based on the dropdown selection. Below is the select tag code which displays the values from the database.
<div class="col-md-4 mb-5">
<select class="selectpicker show-tick" data-width="fit" id="test" data-header="Choose Cost Type Description" title="Choose Cost Type Description">
{% for row in odrrows %}
<option name="costtypedesc" value = "{{ row.odr_cost}}">{{ row.odr_cost_desc}}</option>
{% endfor %}
<select>
</div>
Is there a way fetch row.odr_cost value to same page instead of row.odr_cost_desc that too without submit? I know we can fetch the row.odr_cost_desc value using javascript but not sure about row.odr_cost.
Here is the sample table1
My dropdown displays drinks, liquids and XYZ. When users selects drinks, I would like to display number 52 in the same webpage(maybe with p tag) instead of drinks.

Related

HTMX not triggering correct query on pickadate.js selection

I use django-forms-dynamic package and htmx to dynamically load available options on a MultipleChoiceField. The options are based on a date field, for which I use pickadate.js by Amsul.
The initial query gets the correct choices from the database. However, if the date is changed, the query is lagging one step behind. So, let's asume 1.11.2022 is initially selected. If changed to 4.11.2022, the query is made for the 1.11.2022. If 28.11.2022 is selected, 1.11.2022 is queried, etc.
reservation_form.html
<div class="col-lg-6">
<div class="form-floating">
{% render_field reservation_form.date class="datepicker form-control mb-3"
hx-get="/reservation/filter-seats"
hx-include="#id_dinner"
hx-trigger="click change"
hx-target="#id_seat_reservation"
%}
<label for="id_date">Dinner Date</label>
</div>
<div class="form-floating">
{% render_field reservation_form.amount_guests class+="form-control" placeholder="" %}
<label for="id_amount_guests">Guests</label>
</div>
<div class="visually-hidden">
{% render_field reservation_form.dinner %}
</div>
<div class="form-check">
{% render_field reservation_form.seat_reservation class+="form-select" %}
<label for="id_seat_reservation">Select Seats</label>
</div>
</div>
pickadate script
<script>
var $input = $('.datepicker').pickadate({
format: 'yyyy-mm-dd',
formatSubmit: 'yyyy-mm-dd',
min: 0,
max: 90,
disable: {{ blocked_dates }},
firstDay: 1,
})
var picker = $input.pickadate('picker')
</script>
What am I missing?
You have set the triggers as hx-trigger="click change". First, this is incorrect, you have to separate events with a comma, right now HTMX tries to evaluate change as a trigger modifier without success. Therefore you only have the click trigger event, HTMX submits the form when you click on the input element. At the same time pickadate.js also listens to the click event and opens the datepicker widget. After selecting a date the form dispatches the change event, but you have disabled that for HTMX so it will not submit the form again. Next time you click on the input element HTMX submits the form with the previously selected value.
To fix the issue just remove the hx-trigger attribute. For input fields the default trigger is already the change event, therefore HTMX will submit the form when pickadate.js enters the selected date into the input field.

How to pass a <select> in a View using Django

I was trying to make a cart system in Django and wanted to pass Size and the Quantity of product as <Select>
input in View.
My Template have :
<ul class="list-unstyled">
Select Size:
<select name="sizes">
{% for size in product.sizes.all %}
<li class="list-item list-inline-item"><option value="{{size.nameSize}}">{{size.nameSize}}</option> </li>
{% endfor %}
</select>
</ul>
This is how it looks :
But when i Submit it using the Add to Cart Button i get error:
This is the code in the view:
def add_item(request,pk):
product = get_object_or_404(Product,pk=pk)
size = request.POST['sizes']
selectsize = Size.objects.get(nameSize=size)
user = request.user
usercart = Cart.objects.get(owner=user)
newitem = CartItems.objects.create(cart = usercart,product=product,size=selectsize)
items = usercart.cartitems
return render(request,'cart.html',{'cartitems':items})
I am trying to use the name of the size from the Template and compare the size name i have in the database for that product Using:
selectsize = Size.objects.get(nameSize=size)
I was able to get size with name 36 so i wanted to pass the value 36 from the template to the variable size using post.
But i get the error mentioned which i believe is because name for the <select> is common in all the <option>.
If i can either get an alternate way to do that or solve this error both type of solutions are welcomed.
*I am not using Django Forms because i don't know how to have django form display like i am displaying my products in cart and on the product page.
ANSWER
I was missing a submit button and was rather using a <a href="{% url 'add_item' product.pk %}>Add To Cart</a>" to submit the form which was not working.
Now i replaced it with <button class="btn btn-success" style="margin-top: 10px;" type="submit">Add To Cart New</button>
And the form Action is given the link i was trying to go to.
<form method="post" enctype="multipart/form-data" action="{% url 'add_item' product.pk %}">
A silly mistake on my side.
Thanks for the answers.
Expanding on what #Yevhenii M. said, and talking particularly about the MultiValueDictKeyError:
This error happens when the given key (sizes in this case) is not found in the POST dict. This might be happening (i'm only guessing, since you didn't post the full html code), because you didn't put the corresponding <form> tag surrounding the select.
So, the final code would look something like:
<form action="url-to-send-form-data" method="POST">
{% csrf_token %}
<select name="sizes">
{% for size in product.sizes.all %}
<option value="{{size.nameSize}}">{{size.nameSize}}</option>
{% endfor %}
</select>
</form>
The {% csrf_token %} is needed in order to protect you against Cross Site Request Forgery attacks (more info: https://docs.djangoproject.com/en/2.2/ref/csrf/)
EDIT: Now that I take a closer look, the error message shows that the url is being called with a GET request (maybe because of trying to access to /item_added/1 straight from the browser's url). That is why django can't find the sizes key.
One common way to call the url via post, is as shown in the code snipet above, and adding a submit button to the html:
...
<button type="submit">Submit</button>
</form>
You don't need to use <ul> tag here.
You can write:
Select Size:
<select name="sizes">
{% for size in product.sizes.all %}
<option value="{{size.nameSize}}">{{size.nameSize}}</option>
{% endfor %}
</select>
and result will be the same.
Since you didn't specify that add_item(request, pk) works only by POST, then you can't expect that request.POST always will be presented.
Better write your code as this:
if request.POST:
# do something
And if you don't specify default value for your select in template, then sizeswill not be in your request.POST.
You can write like this just to be sure that you got some value:
request.POST.get('sizes', 'some_default_value')
Just because you get MultiValueDictKeyError you need to see what you get in request. Maybe you get QueryDict, then you need to extract first value. For example, see this SO question. For example, print your request.POST or check type.

How to get the information of a specific object that is retrived from a django model using for loop

I have a boostrap slider which is populating using for loop and django model objects now I want that if I click on any of the slider object then it show me the information related to that specific object which I clicked the Information must be retrived from the django model.
Thanks In Advance please help me to get out of this situation ..
Here is my code which is populating the slider. I want when I clicked on any object in the loop it should only show me the information related to that object or How can I access and display the name and description of individual product diplayed using for loop in django
{% for product in products %}
<div class="services-block-two">
<div class="inner-box">
<div class="image">
<img src="/{{ product.prd_logo }}" alt="" />
</div>
<div class="lower-content">
<h3>{{ product.prd_name }}</h3>
<div class="text">{{ product.prd_des }}</div>
Read More <span class="arrow flaticon-next"></span>
</div>
</div>
</div>
{% endfor %}
here is a image of product i want to display the name,logo and description of the product on different web page when user would click on that product

Django form submit on dropdown selection rather than submit button

I have a table with lots of job data, and I have a dropdown menu and a submit button, which acts as a filter, so that the table only displays jobs based on the filter:
<form>
<select id="user_id_dropdown" name="user_id">
<option disabled selected>Filter by Username</option>
<option value="all">All Usernames</option>
<option disabled>────────────</option>
{% for user in users %}
<option value={{ user.id }}>{{ user.username }}</option>
{% endfor %}
</select>
<input id="filter" class="btn btn-primary" type="submit" value="Filter" />
</form>
<table>
...
How I've done it with the button is such that the user_id of the username is passed as a query string and my view handles it. Upon selecting a username (say it's user_id is 4) and clicking the submit button, the url is:
http://...jobs?user_id=4
Then I have a table below where all the jobs displayed are now only those created by user_id 4.
The thing is, now I just want to do away with the submit button and just submit the form on dropdown selection.
I've tried to give the form a name and to submit when there is a change on selection:
<form name='filter' method=POST>
<select id="user_id_dropdown" name="user_id" onChange="filter.submit();">
...
But this doesn't seem to work. It does seem like the page reloads (similar to the submit button), but the table data doesn't change. What am I missing out here?
I tried this:
onChange="form.submit();"
and it worked. Seems the name is not necessary.
Try putting this on your onchange attr:
document.filter.submit();
If this fails, give your form an ID attribute and do:
document.getElementById('youFormId').submit();
You could also send it as a GET paramenter like:
onchange="window.locatio.href+='?v='+this.value;"
By the way this question has little relation with Django, you should tag it html/javascript next time you ask about this kind of stuff.

Issues with feeding data into database when using for loop

In my template I have used for loop for some fields
<div class="register_div">
<p>Title:</p>
<p>{{ form.title }}</p>
</div>
<div class="register_div">
<p>Upload Images :</p>
<p>{{ form.image }}</p>
</div>
{% for item in product %}
<div class="register_div">
<p>{{ item.Name }} <input type="text" name="custom[{{item.id}}]"/></p>
</div>
{% endfor %}
<div class="register_div">
<p>Price:</p>
<p>{{ form.price }}</p>
</div>
As code shows there is one field which using for loops if that field has three records then in the form it shows three text boxes so that user can feed data to all three fields, but my table in database have only one col for his id and one for his vaue.
so how i can feed data to my database so that if user feels all three text boxes then it can be easily stored in to my database.
If it is possible by three duplicate entry for title , image and price then its ok,But it should have take three different item name and there corresponding value.
e.g.
if there are three item names comes out from for loop then what user see is.
title
image
item 1 ---> its vaue
item 2 ---> its vaue
item 3 ---> its vaue
price
now it should we store in database like
id title image item_name item_value price
1 asd a.jpg item1 value 1 1111
2 asd a.jpg item2 value 2 555
3 asd a.jpg item3 value 3 789
or there is any another efficient way to do this please let me know
The "efficient way" to do this is to make sure your models match this data, and then use Model FormSets.
If, for some arcane reason, you don't want to define models to match your data, you can use normal formsets instead.
If you aren't familiar with Django forms, I highly recommend you try to understand those first. This answer by yours truly has a fairly comprehensive walkthrough on django forms.