I have a Search form that includes the query box, some checkbox items, and a start and end date. I am getting my information when I enter a query, so I know it is performing the search_results action, but the start and end date is not getting validated at all. I have yet to add the code to handle the start and end date in my results, but the issue is there is no client side validation happening on the form.
My form looks like this:
class SearchForm(forms.Form):
q = forms.CharField(max_length=64,required=False)
service_choices = forms.MultipleChoiceField(
required=True,
widget=forms.CheckboxSelectMultiple,
choices=CustomUser.SERVICE_CHOICES,
)
start_date = forms.DateField(required=False)
end_date = forms.DateField(required=False)
I tried using Class Based View, but did not get any fields at all, so I
tried using a function based view to get my search criteria.
The view looks like:
def get_search(request):
form = SearchForm()
return render(request, 'get_search.html', {'form':form})
My template is:
<!-- templates/get_search.html -->
{% extends "base.html" %}
{% block title %}Search{% endblock title %}
{% block content %}
{% if user.is_authenticated %}
<br><br>
<TABLE BORDER="0" WIDTH="100%">
<TR>
<TD ALIGN="Left"><B>Track X - search</B></TD>
<TD ALIGN="Center"><B>User: {{ user }}</B></TD>
<TD ALIGN="Right"><B>Service: {{ user.service }}</B></TD>
</TR>
</TABLE>
<form action="{% url 'search_results' %}" method="get"">
{% csrf_token %}
<TABLE BGCOLOR="#66CCCC" Border="2" WIDTH="100%">
<TR>
<TD ALIGN="Left" WIDTH="100"> Services:</TD>
<TD ALIGN="Right">Search expression:</TD>
<TD ALIGN="Left">
{{ form.q }}
<button type="submit" name="submit">Search TrackX</button>
</TD>
</TR>
<TR>
<TD WIDTH="100"> {{ form.service_choices }} </TD>
<TD COLSPAN="2" ALIGN="Center"> Start Date: {{ form.start_date }}
End Date: {{ form.end_date }}</TD>
</TR>
</TABLE>
</form>
{% else %}
<p>You are not logged in</p>
Log In |
Sign Up
{% endif %}
{% endblock content %}
The Search_results view just uses the query to build some Q Filter
queries, and it seems to be working correctly.
It originally used a GET Method, and was passing the parameters into the search results view just fine. It just doesn't validate the dates (or anything else I assume) before passing the parameters into the view.
Can anyone tell me what am I missing here?
As I see on the view that your posted, you are not actually checking if the form is valid, you can do that by using:
if request.method == 'POST':
form = SearchForm(request.POST)
form.is_valid()
This method will validate all your fields, and return the boolean value representing if its valid or not.
Related
I saw where I can Have a page break in a easy pdf html template saying
<p class="pb"></p>
That is great, but I am trying to run a report where it page breaks and puts a table header every so many lines, with special consideration for the first page. Is there anyway to do this?
This is the view I am calling my html from:
class InvoiceReportIDPDF(PDFTemplateView):
#template_name = 'ipaswdb/provider/report/provider_profile.html'
template_name = 'ipaswdb/invoice/report/invoice_report_pdf.html'
def get_context_data(self, **kwargs):
context = super(InvoiceReportIDPDF, self).get_context_data(pagesize='LetterSize',title='Invoice',**kwargs)
#print "provider id: ", kwargs['pk']
self.download_filename = 'invoice-report-' + kwargs['pk'] + '.pdf'
res = build_invoice_printout_models(kwargs['pk'])
#res = build_invoice_printout_models('all')
return context
So I can print this invoice but the line items just run from one page to the next with no nice header at the top of the next page (for when same invoice)...
I can't use variables in the html page to count using the template and I thought Id get slick and when I build the items I send to the webpage to put in a field for a page break.
So when I build my object I send to the view context I have like:
invoiceItem['pagebreak'] = None
if lineCount > xmany:
invoiceItem['pagebreak'] = 'YES'
Then in the html:
{% if invoice.items %}
{% for item in invoice.items %}
<tr>
<td> {{ item.name}} - {{ item.provspecialty }} </td>
<td> Current Dues </td>
<td> </td>
<td> ${{ item.dues }} </td>
</tr>
<tr>
<td></td>
<td> {{ item.desc }} </td>
<td> ${{ item.adjustments}}</td>
<td></td>
</tr>
{% if item.pagebreak %}
<p class="pb"> </p> <!-- this didn't work right at all -->
<!-- just sent a bunch of blank lines then 5 pages down tried to work-->
{% endif %}
{% endfor %}
{% endif %}
I wish it just 'knew' where the bottom of the page was to make the break and add a new header...
I have a form which needs to take in 1 integer value. This integer value will be an id associated with a row in a html table.
template.html
{% block content %}
<div id="formContainer" class="center top">
<p class="lead">Select simulation session </p>
{% if simulationSessions %}
<table class="table table-striped">
<thead>
<tr>
<th></th>
<th>#</th>
<th>Label</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{% for simulationSession in simulationSessions %}
<tr>
<td><input id="id-{{ simulationSession.id }}" name="idRadio" type="radio" value="{{ simulationSession.id }}"> </td>
<td>{{ simulationSession.id }}</td>
<td>{{ simulationSession.label }}</td>
<td>{{ simulationSession.date.strftime('%d-%m-%y %H:%M') }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="button" class="btn btn-sm btn-success">Analyse</button>
{% else %}
<div class="alert alert-danger" role="alert">
<strong>Oopsadazy!</strong> No simulations are registered in the database for this user. You need to run a simulation session before analyzing it!
</div>
{% endif %}
</div>
{% endblock %}
Each table row has a radio button, and the value from the selected button will be the only thing my form requires. I have decided to go with one hidden IntegerField instead of a RadioField. It is possible to do the latter but then I have to solve the problem of dynamically creating the choices (I decided to go against that when I couldn't pass the list as a parameter when referencing the form from my view.py).
form.py
class SimulationSessionSelectionForm(Form):
simulationSessoinId = IntegerField('simulationSessoinId', validators=[DataRequired()], widget=HiddenInput())
My questions is how can I take the value from the selected radio button and use that as the data for the hidden integer field once the form is submitted?
This could maybe be done with something similar to this inside a script within the html? (this does not compile)
{% set form.id.data %}
this.value
{% endset %}
The view would look something like this:
view.py
#app.route('/dashboard', methods=['GET', 'POST'])
#login_required
def dashboard():
form = SimulationSessionSelectionForm()
if form.validate_on_submit():
redirect('/somewhere')
userkey = models.User.query.filter_by(id = current_user.get_id()).first().userKey
userSimulationSessions = models.SimulationSession.query.filter_by(userKey = userkey).all()
simulationSessions = []
simulationSessionIds = []
for simulation in userSimulationSessions:
simulationSessions.append({'id' : simulation.sessionID, 'label' : simulation.label, 'date' : simulation.date})
simulationSessionIds.append(simulation.sessionID)
return render_template("dashboard.html", simulationSessions = simulationSessions, form = form)
This line in the template adds the hidden field (and the csfr token) to the
{{ form.hidden_tag() }}
I figured I could just set the value of the hidden IntegerField by some jquery script whenever the radio button change event fired. To do this I used the following code:
<script>
$( document ).ready(function() {
$('input[type=radio][name=idRadio]').change(function() {
$('#simulationSessoinId').val(this.value)
});
});
</script>
I've been playing around with Django forms and it's a bit of a headache. I came to a point where I can display my form properly but I only want to edit part of it's data, not all of them.
Specifically: I have a Product model that has a title and a featured bool field. I want a form that displays all the products names with a tickbox next to it. The user is able to edit the featured property of each Product on the same form, but only that! My problem is that with the current setup, the displayed title is also an input field, not a simple text. If I change the template to display {{ productForm.title.value }} instead of {{ productForm.title }} it displays it as a text but the form failes the validation (It requires the title to have a value, since it cannot be null).
Model is plain simple, title and featured fields with CharField and BooleanField types. Validation branch is also not taken care of in the sample but "is_valid()" returns false.
views.py
def featured_product(request):
FeaturedProductFormSet = modelformset_factory(Product, fields=('title', 'featured'))
if request.method == "POST":
productForms = FeaturedProductFormSet(request.POST)
if productForms.is_valid():
productForms.save()
return redirect('/admin/')
else:
productForms = FeaturedProductFormSet()
return render_to_response(
'vetco_app/featured_products.html',
{
'productForms': productForms,
},
context_instance=RequestContext(request)
)
featured_products.html
<form action="" method="post">
<table>
<thead>
<th>
Termék neve
</th>
<th>
Kiemelt
</th>
</thead>
<tbody>
{% for productForm in productForms %}
{% if not forloop.last %}
<tr>
<td>
{{ productForm.id }}
{{ productForm.title }}
</td>
<td>
{{ productForm.featured }}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<p>
{{ productForms.management_form }}
{% csrf_token %}
<button type="submit" name="action" value="Save">Save</button>
</p>
How to make it display only the text of the title without the need to validate it?
Simply provide context:
from django.template import RequestContext
context = RequestContext(request, {"your_model":your_model")
now in templates just write:
{{ your_model.some_attribute }}
template.html
{% extends "base.html" %}
<body>
{% block content %}
<form action="." method="post">
{% csrf_token %}
<table align="center" style="margin-left:60px";>
<p>{{KEBReading_form.as_table}}</p>
<tr><td colspan="2" align="right"><input name="KEBsubmit" type="submit" value="Submit Reading" id="_KEBsubmit1"/> </td></tr>
<tr><td colspan="2" >{{KEBMessage}} </td></tr>
</table>
</form>
<table border="1">
<p> KEB Reading as on Month jan and year 2012</p>
<tr>
<th>Date </th>
<th>Time</th>
<th>True Power Reading</th>
<th>Apparent Power Reading</th>
<th>True Power consumed</th>
<th>Voltage Reading</th>
<th>Power Factor</th>
</tr>
{% for item in q2 %}
<tr>
<td>{{item.date}}</td>
<td>{{item.time}}</td>
<td>{{item.truepower_reading}}</td>
<td>{{item.apparentpower_reading}}</td>
<td>{{item.truepower_consumed}}</td>
<td>{{item.voltage_reading}}</td>
<td> {{item.powerfactor}}</td>
</tr>
{% endfor %}
</table>
{% endblock content %}
views.py
def KEBReading1(request):
#form2 = KEBReading.objects.all()
if request.method == "POST":
form = KEBReading_form(request.POST)
if form.is_valid():
prevdate=KEBReading.objects.latest("date")
# Model.objects.latest('field')
print prevdate.date
print prevdate.time
# q1 = KEBReading.objects.get(datetime.date.today()-datetime.timedelta(0))
kr_truepower_reading = form.cleaned_data["truepower_reading"]
kr_apparentpower_reading = form.cleaned_data["apparentpower_reading"]
truepower_consumed1=kr_truepower_reading-prevdate.truepower_reading
powerfactor1=((kr_truepower_reading-prevdate.truepower_reading)/(kr_apparentpower_reading-prevdate.apparentpower_reading))
#instance=truepower_consumed,powerfactor
## replace form.save() with following lines
form1=form.save(commit=False)
#form1.calculate(truepower_consumed1,powerfactor1)
form1.truepower_consumed=truepower_consumed1
form1.powerfactor=powerfactor1
print form1.powerfactor
form1.save()
q2=KEBReading.objects.latest("date")
context={'KEBReading_form':form,'q2':q2}
return render_to_response('keb.html',context,context_instance=RequestContext(request))
else:
form = KEBReading_form()
return render_to_response('keb.html',{'KEBReading_form':form},context_instance=RequestContext(request))
i want to display all readings in a table whic i calculated through the views in the template. i get model object not iterable while using for loop to iterate..
A few issues:
First, as Aidan correctly noted KEBReading.objects.latest("date") this will return an object, not a collection or iterable.
Secondly, you aren't assigning any of the fields that you are calculating in view. truepower_consumed1=kr_truepower_reading-prevdate.truepower_reading doesn't assign it to your object that you retrieved (your q2). I'm not sure if this is intentional. However, I suspect you want to return to your template the instance of the form, not another record from the table. You need to update your question.
To fix these problems immediately:
<tr>
<td>{{q2.date}}</td>
<td>{{q2.time}}</td>
<td>{{q2.truepower_reading}}</td>
<td>{{q2.apparentpower_reading}}</td>
<td>{{q2.truepower_consumed}}</td>
<td>{{q2.voltage_reading}}</td>
<td> {{q2.powerfactor}}</td>
</tr>
latest() returns the latest object in the table, not a set of objects. Instead of that, you should use KEBReading.objects.all().order_by('date')
Your q2 variable is just an object not a set.
The following line returns a single object -
KEBReading.objects.latest("date")
But your template is expecting a set that it can iterate over -
{% for item in q2 %}
<tr>
<td>{{item.date}}</td>
<td>{{item.time}}</td>
<td>{{item.truepower_reading}}</td>
<td>{{item.apparentpower_reading}}</td>
<td>{{item.truepower_consumed}}</td>
<td>{{item.voltage_reading}}</td>
<td> {{item.powerfactor}}</td>
</tr>
{% endfor %}
Check the docs for the latest() function.
template.html
{% extends "base.html" %}
<body background="100%">
{% block content %}
<!--<table class="table" align="right"style=" margin-right:10px">-->
<form action="." method="post">
{% csrf_token %}
<table align="right" style="margin-right:27px ,margin-top:-20px";>
<p>{{GeneratorService_form.as_table}}</p>
<p>{{FuelUsuage_form.as_table}}</p>
<tr><td colspan="2" align="right"><input name="KEBsubmit" type="submit" value="Submit Reading" id="_KEBsubmit1"/> </td></tr>
<!--<tr><td colspan="2" >{{KEBMessage}} </td></tr>-->
</table>
</form>
<table align="left" border="1">
<p> Generator Service Readings </p>
<tr>
<th>Date </th>
<th>Time</th>
<th>Running time</th>
<th>Next Service Reading</th>
<th>Running Difference</th>
<th>Part Changed</th>
<th>Fuel Type</th>
<th>Fuel quantity</th>
<th>Fuel Balance</th>
</tr>
<tr>
{% for item,item1 in q2,q3 %}
<td>{{item.date}}</td>
<td>{{item.time}}</td>
<td>{{item.runningtime_reading}}</td>
<td>{{item.next_service_reading}}</td>
<td>{{item.running_diff}}</td>
<td> {{item.part_changed}}</td>
<td>{{item1.type}}</td>
<td>{{item1.balance}}</td>
<td>{{item1.quantity}}</td>
</tr>
{% endfor %}
</table>
{% endblock content %}
views.py
def GENService(request):
q2=GeneratorService.objects.all().order_by('date')[:30]
q3=FuelUsuage.objects.all().order_by('date')[:30]
if request.method=="POST":
form=GeneratorService_form(request.POST)
form2=FuelUsuage_form(request.POST)
if form.is_valid():
prevdate=GeneratorService.objects.latest("date")
prevdate1=FuelUsuage.objects.latest("fu_date")
print prevdate.date
print prevdate.time
running_time = form.cleaned_data["runningtime_reading"]
gs_next_service_reading=running_time+250
gs_running_diff=running_time-prevdate.runningtime_reading
form1=form.save(commit=False)
form1.running_diff=gs_running_diff
form1.next_service_reading=gs_next_service_reading
form1.save()
form2.save()
q2=GeneratorService.objects.all().order_by('date')[:30]
q3=FuelUsuage.objects.all().order_by('date')[:30]
print q2.values()
context={'GeneratorService_form':form,'FuelUsuage_form':form2,'q2':q2,'q3':q3} return render_to_response('serv.html',context,context_instance=RequestContext(request))
else:
form = GeneratorService_form()
form2=FuelUsuage_form()
return render_to_response('serv.html',{'GeneratorService_form':form,'FuelUsuage_form':form2,'q2':q2,'q3':q3},context_instance=RequestContext(request))
how to use two lists in a for loop in a template. im gettting a error Could not parse the remainder: ',q3' from 'q2,q3'.basically im combining two forms in a template and want to display the data from the database in the same template
You don't want to do that. Presumably there is some sort of relationship - ForeignKey, OneToOne, ManyToMany - between those two models? If so, you should iterate through one of them, and follow the relationship to get the related item.