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

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

Related

Django: Cannot reference a fieldname in template which contains a dot

The object which I pass from view to template has a few fields which are dynamically incremented and allocated
e.g the object looks like:
row = {
'id':id,
'input.object1':obj1
'input.object2':obj2
}
I am trying to access the value of "input.object1" as "{{ row.input.object1 }}" in template.
but the page does not show anything for this field (same problem for "input.object2". But "row.id" works fine)
{% for row in row_list %}
<tr>
<td>{{ row.id }}</td>
<td>{{ row.input.object1 }}</td>
<td>{{ row.input.object2 }}</td>
</tr>
{% endfor %}
Is there anyway to access these values in html ?
Thanks in advance :)
You can try the following structure of your context:
row = {
'id': id,
'input': {'object1': obj1, 'object2': obj2}
}
which will allow you to access the values the way you try it in your template. But if that structure is dynamic and variable in length, you are better off using a list:
row = {
'id': id,
'input': [obj for obj in ....]
}
and in the template
{% for row in row_list %}
<tr>
<td>{{ row.id }}</td>
{% for obj in row.input %}
<td>{{ obj }}</td>
{% endfor %}
</tr>
{% endfor %}
Django's template languages uses dots in variables names to indicate an index (lists etc), key (dict-likes) or attribute (anything else) lookup, so for {{ row.input.object1 }} it first tries to resolve row.input as either row["input"] or row.input - none of which exists.
You want to make input either a list or dict, ie:
row = {
'id':id,
'input'= [obj1, obj2]
}
and then
{{ row.input.0 }} - {{ row.input.1 }}
or
row = {
'id':id,
'input'= {"object1": obj1, "object2": obj2}
}
and then
{{ row.input.object1 }} - {{ row.input.object2 }}

Check whether value in dict with for loop in Django's template

I have the following data in my views.
months = [1,2,3,4,5,6,7,8,9,10,11,12]
mydict = {3:'a',4:'b'}
The key means month,if this month exists value,then render the value,else leave blank.
Here's my template.
{% for j in months %}
{% if mydict.j %}
<th class="align-middle">{{ mydict.j }}</th>
{% else %}
<th class="align-middle"></th>
{% endif %}
{% endfor %}
But the result always is blank.
I can access the value by mydict.3,but i can't get the value by mydict.j with a forloop.
If you write {{ mydict.j }}, then Django aims to lookup the value mydict['j'], not mydict[j].
Dictionary lookups and function calls (with arguments) are deliberately not allowed in a template, such that developers are encouraged to write business logic in the view not in the template. You can write a custom template filter, or make use of the jinja template renderer to allow this.
But it might be more sensical to do the mapping in the view:
def some_view(request):
mydict = {3:'a',4:'b'}
monthsanddict = [(x, mydict.get(x)) for x in range(1, 13)]
return render(request, 'some_template.html', {'monthsanddict': monthsanddict})
and in the template, you can then render this with:
{% for j, mydictj in monthsanddict %}
{% if mydictj %}
<th class="align-middle">{{ mydictj }}</th>
{% else %}
<th class="align-middle"></th>
{% endif %}
{% endfor %}

Can't render attributes of an objecte linked with M2M field

Trying to render attributes of objects that are linked with another object via m2m field.
#models
class Arm(models.Model):
cmrs = models.ManyToManyField(CMR, null=True)
class CMR(models.Model):
client = models.ForeignKey('Client', on_delete=models.CASCADE,
null=True, default="", blank=True)
The view
if us.groups.filter(name__in = ['prime']):
query_set = Plan.objects.order_by('-pk')
query_ys = Arm.objects.filter(date=ys)
query_rn = Arm.objects.filter(date=rn)
query_tm = Arm.objects.filter(date=tm)
client_rn = query_rn.prefetch_related('cmrs')
args = {'query_rn': query_rn,
'cl_rn': client_rn,
'query_tm': query_tm,
'query_ys': query_ys,
'query_set': query_set
}
return render(request, 'personnel/schedule/test-schedule-full.html', args)
And the template
<tbody id="add">
{% for query in query_rn %}
<tr class="row100 body {{ query.status }}" data-href="/personnel/arm/{{ query.id }}">
<td class="cell100 column1">{{ query.driver }}</td>
<td class="cell100 column2">{% for idem in cl_rn.cmrs.all %} {{ idem.client }} {% endfor %}</td>
<td class="cell100 column3">{{ query.des_from}}</td>
<td class="cell100 columnarrow"><i class="fas fa-arrow-circle-right"></i></td>
<td class="cell100 column4">{{ query.des_to }}</td>
</tr>
{% endfor %}
</tbody>
What I am trying to do is to show all the values of the client field of an CMR objects that are linked with Arm in <td class="cell100 column2"></td> but it shows nothing instead.
It doesn't make sense to have separate querysets for the prefetch_related call. You're iterating through query_rn, you need to define the prefetch_related on that same queryset and then iterate through the related objects from there; you don't need client_rn at all. So:
query_rn = Arm.objects.filter(date=rn).prefetch_related('cmrs')
...
{% for query in query_rn %}
{% for idem in query.cmrs.all %} {{ idem.client }} {% endfor %}
{% endfor %}
Note also, the first line of your code is a bit off. You shouldn't use __in with a single-list element, just check for equality; and since you just want to check that the related group exists, you should use the exists() method, which is slightly more efficient:
if us.groups.filter(name='prime').exists():

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 %}

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

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.