How can submit form with array fields and process on view? - python

I am trying to submit form with array fields and process on Django view. Also, I want to compare the submitted form data with correct answer table data.
question.html:
<form method="post" class="form-inline">
{% csrf_token %}
{% for question in questions %}
<h3>{{ question.title }}</h3>
<div class="radio">
<label class="radio-inline">
<input type="radio" name="ans{{ question.id }}" value="{{ question.option.0 }}">
{{ question.option.0 }}
</label>
</div>
<div class="radio">
<label class="radio-inline">
<input type="radio" name="ans{{ question.id }}" value="{{ question.option.1 }}">
{{ question.option.1 }}
</label>
</div>
<div class="radio">
<label class="radio-inline">
<input type="radio" name="ans{{ question.id }}" value="{{ question.option.2 }}">
{{ question.option.2 }}
</label>
</div>
{% endfor %}
<button type="submit" class="btn btn-success" name="ans_submit">Submit</button>
</form>
view.py:
if request.method == 'POST':
if(request.POST.get('ans_submit')):
temp_context["submitted_answers"] = request.POST.get("ans", "") # Receive as an array?
Expecting to get expert advice.
Thanks

Actually what is posted to you is ans0, ans1, ..., ansN.
So what you want to do is something like this:
answer_fields = [field for field in request.POST if field.startswith('ans')]
for field in answer_fields:
# Do something with `field`...
print(request.GET[field])
Additionally, you might want to check that the latter part is numeric, like so:
[field for field in request.POST
if field.startswith('ans') and field[3:].isnumeric()]

Related

How do I get all for-looped values from a Django template

I am new to django. I want to use this django form to get number_of_days for all {{ name }} values
<div>
<form action="change_number_of_days" method="post">
{% csrf_token %}
{% for name in filenames %}
<input type="number" name="number_of_days" id="number_of_days" value=200>
<label for="number_of_days"> {{ name }} </label>
<input type="hidden" value="{{ name }}" name="name_of_file"><br><br>
{% endfor %}
<button type="submit"> Gem </button>
</form>
</div>
Currently Im only getting the values of the LAST loop(Pizzaria, 200), but I want to get all looped inputs as a POST request
This is my VIEW.py
def change_number_of_days(request):
if request.method == 'POST':
days = request.POST['number_of_days']
print(cleaning_days)
filename = request.POST['name_of_file']
print(filename)
return render(request, 'price_calculation_complete.html')
return HttpResponse("error")
You have explicitly mentioned that - That's why it shows only 200
<input type="number" name="number_of_days" id="number_of_days" value=200>
You have to set the first <input> tag's value to {{ name }}.
<div>
<form action="change_number_of_days" method="post">
{% csrf_token %}
{% for name in filenames %}
<input type="number" name="number_of_days" id="number_of_days" value="{{ name }}">
<label for="number_of_days"> {{ name }} </label>
<input type="hidden" value="200" name="name_of_file"><br><br>
{% endfor %}
<button type="submit"> Gem </button>
</form>
</div>
I figured it out. To anyone interested:
days_list = request.POST.getlist('number_of_cleaning_days')
I had to use .getlist instead of just POST

Force a hidden input to return a fixed value

The following is my current code:
{% for comment in commentlist %} <!-- Comment section -->
<h5>
{{ comment[0] }}
</h5>
<h6>Created {{ comment[1].strftime('%d/%m/%Y at %I:%M%p') }} By: {{ comment[2] }}</h6>
{% if session.username == comment[2] %}
<form action="{{ url_for('detail', slug=entry.slug) }}" class="form-horizontal" method="post">
<input class="form-control" name="commentid" type="hidden">
<div class="form-group">
<div class="col-sm-offset-0 col-sm-1">
<button class="btn btn-default1" type="submit">Delete!</button>
</div>
</div>
</form>
{% endif %}
<br></br>
{% endfor %}
When the button it pressed it should return the value of
{{ comment[3] }}
This value I should then be able to fetch from Flask in the form of
request.form.get('commentid')
Any ideas of how this could be done would be much appreciated!
<input class="form-control" name="commentid" type="hidden" value="{{ comment[3] }}">

Pass value into {{ form.Product_ID }} in HTML Django

i use the
{{ form.Product_PId }}
to make this field
is there anyway to pass this value
{{ Product.PId }}
where the PId is a primary key from another database
and be like this
<input id="id_Product_ID" min="0" name="Product_ID" type="number" value="{{Product.PId}}" required="">
so that the end result would be like
<input id="id_Product_ID" min="0" name="Product_ID" type="number" value="1" required="">
**to sum up the question
is there a way to pass {{ Product.PId }} into {{ form.Product_PId }}
so that the {{ Product.PId }} value could turn into usable number taken from another database**
reference
forms.py
class PlaceOrder(forms.ModelForm):
class Meta:
model = Order
fields = ["Product_ID","HowMany","DateSubmit",]
HTML
{% for Product in Display_Product %}
<form method="post" action="" id="CartInput"> {% csrf_token %}
<div>
{{ form.Product_ID }}
{{ form.HowMany }}
{{ form.DateSubmit }}
</div>
<div>
<input name="Cart{{ Product.PId }}" type="submit" value="Add to Cart">
</div>
</form>
{% endfor %}
views.py
class Catalogue(generic.ListView, ModelFormMixin):
template_name = 'Shop/Catalogue.html'
model = models.Order
form_class = forms.PlaceOrder
def get(self, request, *args, **kwargs):
Display_Product = Product.objects.all()
now = datetime.datetime.now()
*** tried this one but failed, it just pass in the string {{Product.PId}} and not turn into number ***
form = PlaceOrder(initial= {'Product_ID': "{{Product.PId}}"})
context = {
'form': form,
'date': now,
'Display_Product': Display_Product
}
return render(request, 'Shop/Catalogue.html', context)
thanks and sorry for the long question
Using the {{ }} syntax to reference an object is only used in templates.
On your view you should just use Object.id when passing your initial values.
...
# Get the object that you need
product = Product.objects.first()
# Define your initial values
form = PlaceOrder(initial= {'Product_ID': product.id })
this is what i was looking for , found out that i can use different form method and combine them
i will put it out here hope someone might find it useful
<form method="post" action="" id="CartInput"> {% csrf_token %}
<div>
<input name="Product_ID" type="hidden" value="{{ Product.PId }}" >
<input name="HowMany" type="number" value="1" >
{{ form.DateSubmit }}
</div>
<div>
<input name="Cart{{ Product.PId }}" type="submit" value="Add to Cart">
</div>
</form>

Django - Submit multiple forms with one submit button

I'm trying to create a check in page that lists all of the people that have signed up. Each person has an input box that submits the number of hours they were at the event. I want it so that the same form is submitted multiple times for every person; I don't want to have a submit button for every person because there will be several people and it'll be tedious. I'm using a for loop {% for signups in signup %} to loop through the queryset for the people who are signed up.
Here's a screenshot to illustrate:
In the backend, I want it to save the number of hours to the row in the queryset with the matching name.
HTML:
<form action="/events/occ_checkin" class="form" method="POST" id="checkin_{{ signups.id }}" name="checkin_{{ signups.id }}">{% csrf_token %}
{% for form in formset %}
<h5>
<label for="{{ form.fullname.id_for_label }}">***how would I get the attendee's name?***</label>
<input id="{{ form.fullname.id_for_label }}" name="{{ form.fullname.html_name }}" type="hidden" value="***attendee's name here as well***">
<input id="{{ form.hours.id_for_label }}" name="{{ form.hours.html_name }}" step="0.01" type="number" class="form-control" value="{{ events.hours }}">
</h5>
{% endfor %}
<button class="btn btn-primary btn-block" type="submit">Submit</button>
</form>
Using modelformset_factory worked.
HTML:
<form action="/events/occ_checkin" class="form" method="POST" id="checkin_{{ signups.id }}" name="checkin_{{ signups.id }}">{% csrf_token %}
{% for form in formset %}
<h5>
<label for="{{ form.fullname.id_for_label }}">{% for signups in signup %}{% if forloop.parentloop.counter == forloop.counter %}{{ signups.fullname }}{% endif %}{% endfor %}</label>
<input id="{{ form.fullname.id_for_label }}" name="{{ form.fullname.html_name }}" type="hidden" value="{% for signups in signup %}{% if forloop.parentloop.counter == forloop.counter %}{{ signups.fullname }}{% endif %}{% endfor %}">
<input id="{{ form.hours.id_for_label }}" name="{{ form.hours.html_name }}" step="0.01" type="number" class="form-control" value="{{ events.hours }}">
</h5>
{% endfor %}
<button class="btn btn-primary btn-block" type="submit">Submit</button>
</form>
For views.py and forms.py I just followed the documentation on formsets.

Is it possible to instantiate a formset which isn't call with {{ formset.as_p }}?

I call a formset but not with {{ formset.as_p }} because I want to change the display of forms.
I know when using {{ formset.as_p }} it is possible to instantiate a field to edit it directly.
But is that possible using a formset that way
<form method="POST" action="">
{{ formset.management_form }} {% csrf_token %}
<table>
<!-- <br>{{ formset.as_p }}<br> -->
{% for question in questions %}<hr>
<label for="question">{{ question }} [{{ question.id }}]</label>
<input type="hidden" id="id_form-{{ forloop.counter0 }}-question" name="form-{{ forloop.counter0 }}-question" value="{{ question.id }}"/>
</p>
<p>
<label for="answer">Answer :</label>
<input type="text" id="id_form-{{ forloop.counter0 }}-answer" name="form-{{ forloop.counter0 }}-answer" placeholder="answer here"/>
<input type="hidden" id="id_form-{{ forloop.counter0 }}-id" name="form-{{ forloop.counter0 }}-id" value="{{ reply.id }}"/>
</p>
{% endfor %}
</table>
<center><input type="submit" value="Submit" class="btn btn-success" />
Retour</center>
</form>
I wish I could instantiate the fields answer.
I tried passing in a values like this :
{% for reply in question.reply_set.all %}
<p>
<label for="answer">RĂ©ponse :</label>
<input type="text" id="id_form-{{ forloop.parentloop.counter0 }}-answer" name="form-{{ forloop.parentloop.counter0 }}-answer" value="{{ reply.answer }}"/>
<input type="hidden" id="id_form-{{ forloop.parentloop.counter0 }}-id" name="form-{{ forloop.parentloop.counter0 }}-id" value="{{ reply.id }}"/>
</p>
{% endfor %}
But by doing it like this just initializes the values and does not allow to modify
There has a way to do what I wish with this formset structure?
EDIT :
class ReplyForm(forms.ModelForm):
def __init__(self, page_id, *args,**kwargs):
super (ReplyForm,self ).__init__(*args,**kwargs)
self.fields['question'].queryset = Question.objects.filter(page=page_id)
class Meta:
model = Reply
exclude = ('user','creationDate')
If I got you right, you want to customize the view of a form rendered with a formset. Of course, you can do it, since formset is just a set of forms. Render a formset manually and do so with the form as well.
<form method="post" action="">
{{ formset.management_form }}
<table>
{% for form in formset %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.subject.errors }}
<label for="{{ form.subject.id_for_label }}">Email subject:</label>
{{ form.subject }}
</div>
<div class="fieldWrapper">
{{ form.message.errors }}
<label for="{{ form.message.id_for_label }}">Your message:</label>
{{ form.message }}
</div>
# more fields
{% endfor %}
</table>
</form>
In case you have multiple items field (question in your case) in one form you can itterate them and render manually as well:
{% for field in form.question %}
<div class="fieldWrapper">
{{ field.errors }}
<label for="{{ field.id_for_label }}">Some label:</label> {{ field }}
</div>
{% endfor %}

Categories

Resources