Question on Django: Displaying many to many fields - python

I seem to have a problem with Django when it comes Rendering ManyToManyField in a template. I can make it work partially, but I cannot make it work properly as I want it.
Firstly I have an invoice template which displays Invoice details from my data base
#invoice_details.html
{% extends "base.html" %}
{% block content %}
<h2>Invoice Details</h2>
<div id="horizontalnav">
Add an Invoice
Add a Work Order
Add Payment
</div>
<ul>
<div id="list">
{% for invoice in invoices_list %}
{{invoice.client}}<br/>
{{invoice.invoice_no}}<br/>
{{invoice.contract_info}}<br/>
{{invoice.date}}<br/>
{{invoice.work_orders}}<br/>
{% endfor %}
</div>
</ul>
{% endblock %}
In my database, {{invoice.work_orders}} was displayed like the following below. This is because {{invoice.work_orders}} uses a manytomanyfield
<django.db.models.fields.related.ManyRelatedManager object at 0x8a811ec>
Now I tried to change {{invoice.work_orders}} to {{invoice.work_orders.all}} and I got this.
[<Work_Order: Assurance Support Service >]
This sort of works, but I want it to display "Assurance Support Service" only. So I am wondering how I can do this change if possible.

The content of {{invoice.work_orders.all} is a list of Work_Order objects.
If you want to print them, you should iterate the list:
{% for invoice in invoice.work_orders.all %}
{{invoice}}<br />
{% endfor %}

Related

How to filter in HTML using a field from model?

I want to implement a page with check boxes from university's subjects and the user can select which ones are already completed, I code a for loop that displays in the page all subjects from that course, but I want to separate the subjects by semester in a div, but in the same page, can I do this with a custom template tag or filter?
I have tried using .filter on the query, but in this case only returned one specified semester.
The regroup template tag can help.
Example template code:
{% regroup subjects by semester as semester_list %}
{% for semester, grouped_subjects in semester_list %}
<div>
{# your code for semester here #}
<div>
{% for subject in grouped_subjects %}
{# your code for subject here #}
{% endfor %}
</div>
</div>
{% endfor %}
Read more on docs
——
Edit:
regroup relies on ordering of the queryset.
Change the first line in above code to
{% regroup subjects|dictsort:'semester' by semester as semester_list %}

How to put many fields of django-tables2 into one?

I have a django table declared as follow :
class BookTable(tables.Table):
user= tables.TemplateColumn("""{% include 'books/user.html' with user=record.created_by %}""")
books= tables.TemplateColumn(
""" {% if record.g_books.count %}
<div class="panel-body">
{% include 'books/details/detail.html' with book=record %}
</div>
{% else %}
No New Books
{% endif %}
<div>
</div>
""")
actions = tables.TemplateColumn("""{% include 'books/action.html' with book=record %}""")
I want to make changes on the order and some styles of fields and I want to render only one field that groups user, books and actions fields .
Is that possible with django-tables2 or it's a bad way to do so ?
New with django-tables2 , any advice is welcome
Thanks.

How to get with statement working with zinnia tag

I got a problem with iteration on zinnia tag outcome. Let's say that that tag returns a list of some categories, I tried to manage it in few ways:
{% with categories=get_plain_categories %}
{% for category in categories %}
<h1>{{ category }}</h1>
{% endfor %}
{% endwith %}
or simply:
{% for category in get_plain_categories %}
<h1>{{ category }}</h1>
{% endfor %}
But in both ways, it seems to not even run get_plain_categories tag (I made few prints in it), but when I write : {% get_plain_categories %}, it returns list as it's supposed to.
How should I get that working?
Unfortunatelly with tag is not that powerful, you can't use it with output of other tags. You'll have to create your own tag.
As an example you can have a look at the static. It lets you insert a path to a static file with {% static "images/hi.jpg" %} but you can't easily save it to a variable for later use. That's why in Django 1.5 it got a new syntax {% static "images/hi.jpg" as myphoto %} and this way you can later use {{ myphoto }}. This can't be achieved with with.
That said, I can't find any mentions of get_plain_categories in Google, which is weird.

Dynamic session access in templates

I'm trying to access session keys within a loop that needs to be dynamic, I think you'll get what I'm going for by looking at my code that isn't working.
{% for q in questions %}
<div class="question_wrap">
<h2>{{ q }}</h2>
# this does not work
{% if not request.session.get(str(q.id), False) %}
<!-- show them vote options -->
{% else %}
<!-- dont show options -->
{% endif %}
</div>
{% endfor %}
The syntax of Django templates is very limiting in order to prevent people from putting too much logic inside templates and doesn't allow you to pass parameters to methods.
You can prepare a list of tuples already in the view or write a simple template tag for that. The first options is usually easier:
In the view:
questions = [(q, request.session.get(str(q.id), False)) for q in questions]
In the template:
{% for q, has_voted in questions %}
...
{% endfor %}

Blocks within blocks

I'm having problems displaying nested blocks in a template.
eg.
{% for category in categories %}
//code to display category info
{% products = products.object.filter(category = category) %}
{% for product in products%}
//code to display product info
{% endfor %}
{% endfor %}
I'm getting a "Invalid block tag: 'endfor'" error.
Any ideas?
You cannot assign to variables in the Django template system. Your two attempts:
{% products = products.object.filter(category = category) %}
and
{% products = category.get_products %}
are both invalid Django syntax.
Some Python templating systems are PHP-like: they let you embed Python code into HTML files. Django doesn't work this way. Django defines its own simplified syntax, and that syntax does not include assignment.
You can do this:
{% for category in categories %}
//code to display category info
{% for product in category.get_products %}
//code to display product info
{% endfor %}
{% endfor %}
I think you cannot use arguemnts for methods. You have to modify your categories object, so that you kann use:
{% for product in category.products %}
{% products = products.object.filter(category = category) %}
is not recognized as a valid tag in the django template system. Therefore django complains about the missing endfor, although the {% for x in y %) is not the error.
This should work
{% for category in categories %}
{% for product in products.object.all %}
//code to display product info
{% endfor %}
{% endfor %}
But this is not that, what you want to achieve. Simply you are not able to filter on product.objects with the argument category.
You have to write your own tag which takes arguments on filtering or rethink your problem.

Categories

Resources