I am trying to post all checked input checkboxes. The input field is generated by django's for loop as shown below.
From what I have found so far, the below should be working. I believe the issue may be in the fact that the input fields are generated through the forloop, if so, how can I get around this? For each value add to list and post with js?
index.html
{% for q in list %}
{% if forloop.last %}
<form method="POST" name="selectedchecks"> {% csrf_token %}
<div class="qblock">
<label class="pure-material-checkbox">
<input class="selectedchecks" type="checkbox" name="choices[]" value="{{ q }}">
<span>
<p>{{ q }}</p>
</span>
</label>
</div>
</form>
{% endif %}
{% endfor %}
views.py
if request.method == 'POST':
selected_list = request.POST.getlist('choices[]')
What happens is that only the first value of {{ q }} is returned if the first checkbox is selected, if any other checkbox apart from the first is selected, nothing is returned (empty list). Selecting all checkboxes also only returns the first value.
It should POST all selected checkbox values.
Any help is appreciated!
UPDATE
The problem was that the form was being re-initialized for every loop iteration. Setting the <form> tag before the loop fixed the issue!
Related
why is it i cant put value from my database to input type date? even though my query is correct?
{% for feedback in feedbacks %}
<input name="datef" value="{{feedback.dateSubmitted}}" type="date">
{% endfor %}
this is my views.py
feedback = obj.objects.all()
print(feedback)
this is the result for print
<QuerySet [<TrEmployeeSuppliersFeedbackQuestionsSubmittedRecords: mystudent>]>
my models.py
class TrEmployeeSuppliersFeedbackQuestionsSubmittedRecords(models.Model):
.....
dateSubmitted = models.DateField(auto_now_add=True, null=True, blank=True)
.....
the result in my webview
UPDATE: i change my html to this , and this is the result in my webview
html
{% for feedback in feedbacks %}
{{feedback.dateSubmitted}} <input name="datef" value="{{feedback.dateSubmitted}}" type="date">
{% endfor %}
I suspect the formatting is off. The date input probably wants something like year-month-date. Try passing it like this:
<input name="datef" value="{{feedback.dateSubmitted|date:'Y-m-d'}}" type="date">
If the above doesn't work, also try:
<input name="datef" value="{{feedback.dateSubmitted|date:'d/m/Y'}}" type="date">
for all user inputs i think it will be better to use django forms or ModelForms
after that django will format all values for you and it will be more cleaner way to validate user data, and save it to database. for multiple forms you can use formset
in view you create formset:
TrEmployeeSuppliersFeedbackQuestionsSubmittedRecordsFormSet = modelformset_factory(
TrEmployeeSuppliersFeedbackQuestionsSubmittedRecords,
fields=('dateSubmitted ', )
)
formset = TrEmployeeSuppliersFeedbackQuestionsSubmittedRecordsFormSet()
and add formset as parameter to your html template
and then in html template you can
{{ formset.management_form }}
{% for form in formset %}
{{ form.dateSubmitted.value }} {{ form.dateSubmitted }}
{% endfor %}
I am currently working on my college management application, where staff can enter internal marks of students and the student can view their marks. What i am stuck with is, i want a populate a list of forms to fill the internal marks of each student and submit it at once.
I tried modelformset with the code below and it work exactly as below
formset = modelformset_factory(Internal, fields=('student','marks1','marks2','marks3'))
if request.method == "POST":
form=formset(request.POST)
form.save()
form = formset()
return render(request, 'console/academics/internals.html',{'form':form})
For the model
class Internal(models.Model):
student = models.ForeignKey(User, on_delete=models.CASCADE)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
marks1 = models.IntegerField(default=0)
marks2 = models.IntegerField(default=0)
marks3 = models.IntegerField(default=0)
marks = models.IntegerField(default=100)
marksob = models.IntegerField(default=0)
def save(self):
self.marksob = (self.marks1 + self.marks2 + self.marks3)/15
return super(Internal, self).save()
I want the form to be rendered in html using <input> and not passing {{form}} in html. And moreover I want the form to display only the entries of particular students based on a query. Can anyone help me on this?
I want the form to display only the entries of particular students based on a query.
As stated in the docs, you can specify a queryset for your formset:
formset = modelformset_factory(Internal, queryset=Internal.Objects.filter(...), fields=('student','marks1','marks2','marks3'))
I want the form to be rendered in html using and not passing {{form}} in html
You can do that by iterating over fields, just like normal forms:
<form method="post"> {% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{% for field in form %}
{{ field.label_tag }} {{ field }}
{% endfor %}
{% endfor %}
</form>
More details at using the formset in the template.
Edit
If you want to use custom css classes for your form fields, you can do:
<form method="post"> {% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
<div class="...">
{{ form.marks1.errors }}
<label for="{{ form.marks1.id_for_label }}">Your email address:</label>
<input type="number" name="{{ form.marks1.name }}" value="{{ form.marks1.value }}" class="css-class">
</div>
<!-- and for other fields as well -->
{% endfor %}
</form>
In my flask application I have to draw a form multiple times on the same page. This leads to the problem where I have multiple input fields with the same id on the page. E.g.:
class ChannelForm(flask_wtf.Form):
name = StringField('name')
together with this template:
<form>
{{ form.name }}
</form>
...
<form>
{{ form.name }}
</form>
lead to two input elements with the same id:
<input id="name" name="name" value="" type="text">
Is there an official way to disable adding the id attribute?
Quick n' dirty:
I've found that the following works well: instead of using the field directly, I wrap them in a jinja macro:
{% macro render_field(field) %}
<label>
<span>{{ _field.label.text }} </span>
{{ field(id=False, **kwargs) }}
</label>
{% endmacro %}
which can be used like this:
{% from "_formhelpers.html" import render_field %}
{{ render_field(form.name) }}
The trick here is to pass id=False when rendering the field.
using the meta object:
_Auto = object()
class NoIdAttributeMeta(DefaultMeta):
"""
Surpresses rendering the `id' attribute.
"""
def bind_field(self, form, unbound_field, options):
"""
Raises TypeError in case 'id' is given as a positional arg when constructing a field.
If this happens, make this code smarter or pass `id' as a keyword arg.
"""
# we check `id' at rendering time and if it is still _Auto, do not render it
unbound_field.kwargs.setdefault('id', _Auto)
return super().bind_field(form, unbound_field, options)
def render_field(self, field, render_kw):
if field.id is _Auto:
field.id = False
return super().render_field(field, render_kw)
class MyForm(flask_wtf.Form):
Meta = NoIdAttributeMeta
or be pragmatic:
You could also add a different prefix to each instance of your form and therefore you'd have unique ids:
my_form = MyForm(prefix="form1")
pass
I think you can pass a custom id to the field constructor like this:
<form>
{{ form.name(id_='yourId') }}
</form>
...
<form>
{{ form.name(id_='yourId2') }}
</form>
You don't need id=False because you already can set id when you call render_field()
{% macro render_field(_field) %}
<label>
<span>{{ _field.label.text }} </span>
{{ _field(**kwargs) }}
</label>
{% endmacro %}
Usage:
{{ render_field(field, id=False) }}
Explaination:
Because you have ****kwargs**, you can make the id=False and that would be more dymanic. You can choose when to remove ID.
Hope this help for those who have googled this solution
So I'm rendering a template, including a table...and for one of the columns, the value is blank or contains a Delete button/form (depending on whether delete is possible).
Anyway, my issue is that if the Delete button is present the row height is twice that of the others, making my table look rather ugly.
{% if condition %}
<td>
<form name="input" action="./delete/" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="submit" name={{item}} value="Delete">
<input type="hidden" name="filter_start" value={% if date1 %}{{date1}}{% endif %}>
<input type="hidden" name="filter_end" value={% if date2 %}{{date2}}{% endif %}>
</form>
</td>
{% else %}
{% endif %}
Is there anything clearly wrong with the above? The "hidden" bits are so that I can retrieve certain 'dates' with the 'delete' button.
Try to add style="display:inline;" on the form.
I have this code(which doesn't give me expected result)
#subject_content.html
{% block main-menu %}
{% include "subject_base.html" %}
{% endblock %}
#subject_base.html
....
....
<div id="homework" class="tab-section">
<h2>Homework</h2>
{% include "subject_file_upload.html" %}
</div>
child template:
#subject_file_upload.html
<form action="." method="post" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="submit">
</form>
and my view
#views.py
#login_required
def subject(request,username, subject):
if request.method == "POST":
form = CarsForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect("/")
form = CarsForm()
return render_to_response('subject_content.html', {'form':form}, context_instance=RequestContext(request))
The above code creates HTML in the way I want it to be, however the form does not update database.
BUT,
If I skip the middle template and go directly to the uploading form, it works fine:
#subject_content.html
{% block main-menu %}
{% include "subject_file_upload.html" %}
{% endblock %}
Help me please to make it work with middle template.
I want to do this, because I don't wan't to type the same code more than once.
Like #Besnik suggested, it's pretty simple:
{% include "subject_file_upload.html" with form=form foo=bar %}
The documentation for include mentions this. It also mentions that you can use only to render the template with the given variables only, without inheriting any other variables.
Thank you #Besnik