Django using Updateview for vote Form - python

I want to replace the DetailView in Djangos Poll Tutorial with a UpdateView. Unfortunately what it is showing is a List of Polls instead of a list of Choices + Votes.
My models Poll, Choices are unchanged. The template for the voting view is kept simplest:
<h1>{{ poll }}</h1>
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Vote" />
</form>
How can I have the form to show a specific poll and a list of the choices as in the manually build form of the detail view in the tutorial:
<form action="{% url 'polls:vote' poll.id %}" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>

Use the ModelChoiceField and RadioSelect widget:
class ChoicesForm(forms.Form):
choice = forms.ModelChoiceField(queryset=Choice.objects.none(),
widget=forms.RadioSelect,
required=True,
empty_label=None)
def __init__(self, *args, **kwargs):
poll = kwargs.pop('poll')
super(ChoicesForm, self).__init__(*args, **kwargs)
self.fields['choice'].queryset = poll.choice_set.all()
form = ChoicesForm(poll=poll)

Related

Display two ModelForm class in a single Django html page

I am trying to create 2 forms and display it in a single Django HTML page. I created 2 Modelform class like this
class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = "__all__"
class ToyForm(forms.ModelForm):
class Meta:
model = Toy
fields = "__all__"
In the HTML page I am only able to embed the model = Company. How can I embed the Model = Toy in the same page, what I tried brings up the same Company Form. Here is the html code
<form method="post">
{% csrf_token %}
<h2> Company Form </h2>
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
<form method="post">
{% csrf_token %}
<h2> Toy Form </h2>
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
In views.py
from django.shortcuts import render
from myapp.form import CompanyForm, ToyForm
def index(request):
cform = CompanyForm()
tform = ToyForm()
context={'cform':cform, 'tform':tform}
return render(request,"index.html",context)
In HTML Page
<form method="post">
{% csrf_token %}
<h2> Company Form </h2>
{{ cform.as_p }}
<input type="submit" value="Submit" />
</form>
<form method="post">
{% csrf_token %}
<h2> Toy Form </h2>
{{ tform.as_p }}
<input type="submit" value="Submit" />
</form>

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

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.

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

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()]

Categories

Resources