Jinja2 template does not print query results. "UndefinedError: 'q' is undefined" - python-2.7

class TablePage(BaseHandler):
def get(self):
ID_id = self.request.get('ID')
key = db.Key.from_path("PQ", ID_id)
p = PQ.get(key)
qs = db.Query(QA)
qs.ancestor(p)
result = qs.get()
template_values = {'qs': qs,
'p': p
}
self.render_template('table.html', template_values )
I am asking this question because I am trying to put the queried records into an html table. Are my template_values correct and adequate or do I have to include the values of the variable "result" in template_values somehow also?
Using the same kind of "for" loop in my python code as I used in the jinja2 template, I have added this extra debugging code which shows that there are two instances of QA in qs, but the error persists.
for q in qs:
answers = q.answers
logging.info("answers %s" % answers )
INFO 2012-07-05 09:23:03,853 views.py:84] answers [0L, 0L, 0L]
INFO 2012-07-05 09:23:03,853 views.py:84] answers [0L, 0L, 0L]
I am trying this but the jinja2 template does not seem to be getting the information correctly. For example I have the following template code which produces the error "UndefinedError: 'q' is undefined"
<tbody>
{% for q in qs %}
<tr>
<td> {{ q.seqnum }} </td>
<td> {{ q.question }} </td>
{% for answer in q.answers %}
<td> {{ answer }} </td>
{% endfor %}
<td> {{ q.answers|sum() }} </td>
{% endfor %}
<td>{{ q.date }}</td>
<td>{{ q.modified }}</td>
</tr>
</tbody>

The {% endfor %} in the html template was premature; it needs to be after all the q.xxx values. d'oh
Sorry for wasting other's time.

Related

Summarizing values for each row in a table dynamically generated from django context variables

So I have the following table in my template:
<tbody>
{% for user in users %}
<tr>
<td>{{ user.title }} </td>
{% for fruit in fruits %}
{{ sum|add:user|get_attr:fruit }}
<td>{{ user|get_attr:fruit }} </td>
{% endfor %}
{% for vegetable in vegetables %}
{{ sum|add:user|get_attr:vegetable }}
<td>{{ user|get_attr:vegetable }} </td>
{% endfor %}
<td>{{ sum }}</td>
{% endfor %}
</tbody>
"fruits" and "vegetables" are lists passed as context from the view. The following custom filter allows me to iterate through those lists extract integer values from the model "user". The table columns are generated the same way, so this filter has to be in the table:
#register.filter
def get_attr(obj, attr):
return getattr(obj, attr)
The variable "sum" is passed as context from the view with the value 0. I'm trying to make it summarize all the relevant row variables in the template, but it remains 0. As far as I can see there are three ways I could go about this:
Solve this in the template (as I'm trying now)
Generate the value in the view (although I have no idea how I would go about this)
Add some JS to solve it (would prefer to avoid this).
How should I go about solving this?
Solved this on the back end by generating a dictionary:
views.py
sum = {}
for user in users:
identity = user.pk
score = 0
all_food = fruits + vegetables
for food in all_food:
score += getattr(user,food)
sum[identity] = score
The summarized value can now be accessed in the template by using another custom template tag:
#register.filter
def get_value(dictionary, key):
return dictionary.get(key)
Adding it to the template:
{{ sum|get_value:user.pk }}

Django Form Not Validating my Date fields

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.

Outer loop value does not matches with inner loop value: Django template

I have written a nested loop and doing value comparison between data coming from outer loop with inner loop. Below is my template code :-
<tbody>
{% for col in filter2.qs %}
<tr>
{% for mso in filter1.qs %}
{{ col.box_id }} vs {{ mso.box_id }}
<br>
{% if mso.box_id == forloop.parentloop.col.box_id %}
<td>{{ mso.mso_id }}</td>
<td>{{ col.box_id }}</td>
<td>{{ col.channel_id }}</td>
{% endif %}
{% endfor %}
</tr>
{% empty %}
<tr>
<td colspan="5">No data</td>
</tr>
{% endfor %}
</tbody>
Problems are :
When i do print {{ col.box_id }} vs {{ mso.box_id }} i can see values
When i do print {{ col.box_id|length }} vs {{ mso.box_id|length }} i see length of outer loop value as 0.
If condition below the prints never runs hence no data is inserted in the table.
I am getting data for both the loops from views.py
def search(request):
user_list1 = VCB_Execution_Details.objects.all()
user_filter1 = ReportFilter_VCB_Execution_Details(request.GET, queryset=user_list1)
user_list2 = VCB_Details.objects.all()
user_filter2 = ReportFilter_VCB_Details(request.GET, queryset=user_list2)
print(user_filter2.qs)
print(type(user_filter1))
return render(request, 'user_list.html', {'filter1':user_filter2,'filter2': user_filter1})
filters.py
class ReportFilter_VCB_Execution_Details(django_filters.FilterSet):
class Meta:
model = VCB_Execution_Details
fields = ['box_id','channel_id']
class ReportFilter_VCB_Details(django_filters.FilterSet):
class Meta:
model = VCB_Details
fields = ['box_id','mso_id']
So Finally i got the answer, problem was the object type was VCB_Execution_Details vs str. I tried checking the data type in def search(request): by printing variable type for each data in queryset of user_list1 and user_list2

Django, I want to take an input from a form and contents of the template should be according to the input

models.py
class Transaction(models.Model):
created_date = models.DateField('created_date')
price = models.IntegerField(default=0)
abc = models.IntegerField(default=0)
pqr = models.IntegerField(default=0)
ghi = models.IntegerField(default=0)
Then I take a user input
input.html
<form method="POST" action="search/" style="margin-left:5em;">
{% csrf_token %}
<input type="radio" name="account" value="price"> price<br>
<input type="radio" name="account" value="abc"> abc<br>
<input type="radio" name="account" value="pqr"> pqr<br>
<input type="radio" name="account" value="ghi"> ghi<br>
</form>
views. py
def search(request):
if request.method == 'POST':
search_id = request.POST.get("account", None)
selected_transactions = Transaction.objects.exclude(search_id=0)
return render(request, 'stats/account_details.html', {'selected_transactions': selected_transactions,
'search_id': search_id})
else:
return render(request, 'stats/index.html')
I have to display contents based on user input.
account_details.html
<table>
<tr>
<th>Transaction date</th>
<th>{{ search_id }}</th>
</tr>
{% for transaction in selected_transactions %}
<tr>
<td>{{ transaction.created_date }}</td>
<td>{{ transaction.{{ search_id }} }}</td>
</tr>
{% endfor %}
</table>
I have two issues here.
1.Transaction.objects.exclude(search_id=0) doesn't work. It does not take the value of variable search_id. How do I exclude dynamically those transactions where user input attribute=0?
2.{{ transaction.{{ search_id }} }} in account_details.html doesn't work as it is a syntax error. I need to display data varying on user input. How do I use two variables inside a single tag in my template?
I get that I can resolve both using if else statements, but I have a large no. of attributes. So, is there a shorter way to do it?
Any help is appreciated.
Issue 1: You are trying to use an attribute in a query set filter which is not present in your model. You might want to use any of your attributes of your model like price or any other attribute.
Issue 2: Code below:
<td>{{ transaction.created_date }}</td>
<td>{{ transaction.{{ search_id }} }}</td>
is not correct for various reasons. First thing that you are trying to access created_date attribute which is not present in your queryset attribute. Either you have to remove this attribute or add it into your model. Your second line is incorrect because its a syntax error. Below one might be helpful to you and its syntactically correct.
<td> {{ search_id }} </td>
Edit: You can put if else to compare which search_id is selected by the user and based on that corresponding data can be displayed.
{% if search_id == "abc" %}
{{ transaction.abc }}
{% elif search_id == "pqr" %}
{{ transaction.pqr }}
{% endif %}

Django icontains not working on website as it does in the shell

I am trying to filter based on user input with a simple search form.
Here is the pertinent piece of code from my views.py
def search(request):
error = False
if 'q' in request.GET and request.GET['q']:
q = request.GET['q']
if not q:
error = True
elif len(q) > 20:
error = True
else:
chemicals = Chemicals.objects.filter(Name__icontains=q)
return render_to_response('search_results.html', locals(), context_instance=RequestContext(request))
return render_to_response('search_form.html',{'error':True})
The template
<table>
<th>Barcode</th>
<th>Name</th>
<th>Description</th>
{% for chemical in chemicals %}
{% ifequal chemical.Name q %}
<tr>
<td>{{ chemical.Barcode }} </td>
<td>{{ chemical.Name }} </td>
<td>{{ chemical.Description }} </td>
{% endifequal %}
{% endfor %}
</table>
And the next piece is what I have embedded in search_results.html
An example is that I have a chemical named Nitric Acid. If I put Nitric Acid in the search bar it will display all relevant information for all things with exactly the name Nitric Acid. It is also case sensitive which I thought icontains was not supposed to be. Also searching for Nitric, nitric, Acid, or acid turns up no results which makes me think something is wrong. I used the same command in the shell and it did what I would have expected it to do but it doesn't perform the same on the website. Does anyone have any insight as to why that is the case?
Thanks,
The problem is your ifequal test:
{% ifequal chemical.Name q %}
That doesn't show the row unless the chemical name is exactly equal to q.