django dynamic template link dictonary to object fields - django

I am working on a dynamic template and i hoped to be able to include the last part of it aswell. My problem: I got a x-amount of fields that relate to fields of the object. But when i pass another model object it should show other fields.
Example:
model 1 show object name, category, approved
model 2 show object name, attribute,
For the other variable things, i make a dictionary that holds the information, problem is, i dont know how i could link the object fields to it.
Dictonary send to template:
field_map = {'field1': 'Name', 'field2': 'Category', 'field3': 'Approved'}
Template:
{% if objects|length > 0 %}
<table style="padding: 3px;">
<tr style=" text-align: center;">
{% for key, value in field_map %}
<th>{{ value }}</th>
{% endfor %}
</tr>
{% for object in objects %}
<tr>
<td>{{ object.name }}</td>
<td>{{ object.category }}</td>
<td>{{ object.approved }}</td>
</tr>
But now i want to add the objects fields to the field_map fields.
Cause i will be sending more then 1 object
Hope i explained my question well enough.
Can someone help me out?

You are trying to re-implmenet an already solved problem. Please use django-tables2 to render tables in django: https://github.com/bradleyayers/django-tables2
Update: To answer OP's comment on how to remove or edit the pagination footer:
If you do not want to have pagination to your table then just configure your table passing paginate=None to your RequestConfig like this:
table = TestTable(Test.objects.all())
RequestConfig(request, paginate=None).configure(table)
return render(request, 'test.html', {'table': table})
If you want to edit the footer yourself then you have to provide a new table rendering template. To do this, you just need to copy the contents of table.html from here https://github.com/bradleyayers/django-tables2/blob/master/django_tables2/templates/django_tables2/table.html to your templates directory. You can then modify this file to your requirements, for instance the pagination section is between {% if table.page %} and the {% endif %} at the end of the file.
Now, after you've created your custom table template you need render your table using this template. If you named your template as mytable.html then just use the following syntax from within your normal templates:
{% render_table mytable "mytable.html" %}

Related

Adding rows and columns to HTML table with Django

I have a problem. Consider an HTML table and it has rows and columns. I want to add a new row or column when I want it and I want it to be a record in the database. And I want to do this with django. What should I do?
I think I need to use django_table2 but I don't know how. I would be glad if you write a code sample. Thank you)
Say you have a model, you could get a list of objects like so;
def my_view(request):
context = {'object_list':MyModel.objects.all()}
return render(request, 'mypage.html', context)
Then in the template, you could do a few things to create tables:
Either, fully generate the table with Django, like so:
{% for object in object_list %}
<tr>
<td>{{object.data}}</td>
<td>{{object.data}}</td>
<td>{{object.data}}</td>
</tr>
{% endfor %}
This would create a new row for every object.
Another solution is:
{% for object in object_list %}
//Create row for every object
<tr>
{% for data in object.get_field_data %}
// Create column for every field in object
<td>{{data}}</td>
{% endfor %}
</tr>
{% endfor %}
Where get_field_data would be defined as a method on the model like so:
def get_field_data(self):
datalist = []
for field in self._meta.get_fields():
datalist.append(getattr(self, field.name))
return datalist
You could then even implement some checks on the get_field_data, for example, you could exclude fields.
def get_field_data(self):
datalist = []
for field in self._meta.get_fields():
if field.name != 'id':
datalist.append(getattr(self, field.name))
return datalist
You don't need to use any external package, you can do this easily by using the Django Template Language
Here is a code example using a ListView
# views.py
from django.views.generic import ListView
class ItemListView(ListView):
template_name = 'mytable.html'
model = MyModel
context_object_name = 'item_list'
<!-- mytable.html -->
...
<table>
<thead>
<tr>
<th>Name</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
{% for item in item_list %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.amount }}</td>
</tr>
{% endfor %}
</tbody>
</table>
...
In this way your template will have access to a list of objects called item_list which corresponds exactly to the records in the database table. You can cycle that list/queryset using a for loop that will automatically wrap that content in the html needed to make it part of the table.

How can I use a variable from views.py in a base template for multiple templates?

In a Django application I have several html pages with a similar structure. I am already using a base_site.html template for all my project but for these other pages I would like to use a second template to create tables. These tables could have more or less rows and columns than others.
My idea was that the functions in views.py would send a list of the headers for any given page together with a dict of the data to populate the table, then in the html page I would iterate the list of headers to place the headers in the table then I would iterate the dict to populate the table with the data.
How can I have a table-template.html to use a variable say headers from every function in views.py whenever they are called?
Something like table-template.html
<h1>TEST</h1>
<table>
<tr bgcolor="#ccc">
<th>{% for h in headers %} {{ h }} {% endfor %}</th>
</tr>
</table>
Considering that every function in views.py would return its own headers list
Then how can I use it in any of the html pages
{% extends "admin/base_site.html" %}
{% load static %}
{% block content %}
{% include "table-template.html" %}
{% load static %}
{% for key,value in mydict.items %}
<table>
<tr>
<td>{{ value }}</td>
</tr>
</table>
{% endfor %}
The table-template.html could be use a slight change since you want each value in a tag
<h1>TEST</h1>
<table>
<tr bgcolor="#ccc">
{% for h in headers %}
<th> {{ h }} </th>
{% endfor %}
</tr>
</table>
This will create the correct table headers for you. You can send the headers list from your view render method in the context dictionary.
Feel free to comment if this doesn't give the complete answer you are looking for.
I actually managed to find a solution by creating a template that inherits my base_site.html and on all my other templates I will inherit my new_template.html. So it's kind of a grand parent template inheritance.
I just included all the variables I want in the template (which are all named equally across all functions in views.py) and when the template is extended in a new page it gets the values of the variables from the respective function in views.py.

Django build tables dynamically with filters

SOLVED
Explanation here: Performing a getattr() style lookup in a django template
I am looking to build tables on our business website dynamically. At the moment we have multiple pages with tables and filters that allow for search but I have to go in and construct a table for each of them based on the data that should be displayed. I was hoping to find a way to use one main template file that can encompass most instances for creating a new page. The difficulty I am having is trying to loop through the data and place it in the correct cell.
(Some code has been removed for readability.)
View:
def newDynamicView(request):
jobs = Jobstable.objects.all().order_by('-index')
filter = NewFilter(data, queryset = jobs)
fields_model = filter._meta.fields
fields_text = []
for field in fields_model:
fields_text.append(FIELD_NAME_TEXT[field])
return render(request, 'MYSQLViewer/olivia.html', {'filter': filter, 'fields_model': fields_model, 'fields_display': fields_text})
Current Template (Relevant info):
<div class="table-responsive">
<table id="data_table" class="table table-dark table-bordered table-responsive">
<thead class="thead-light">
{% for field in fields_display %}
<th>{{field}}</th>
{% endfor %}
</thead>
<tbody>
{% for job in filter.qs %}
<tr>
{% for model_field in fields_model %}
<td class="pt-3-half edit {{model_field}}" contenteditable="true" id="{{model_field}}-{{job.index}}">{{job.model_field}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
From what I understand, the problem (and possible solution?) lies in this tag:
{{job.model_field}}
My idea was to grab the job attribute using model_field but obviously, that doesn't work.
In its current state, all data is passed from view to template correctly.
Any help is greatly appreciated.

How to create two columns from a QuerySet in a Django template [duplicate]

I am trying to split a list from my model across two columns, using this html code in the template:
< div class ="col-md-6" >
{%for value in object_list %}
<ul>< ahref="/sites/{{value.url}}/">{{value.Site}}</a></ul>
{% endfor %}
I was planning to achieve this with the slice tag to filter the list, e.g.:
{%for value in object_list|slice:"10:20" %}
It does not work however, and I think it might be because I have context data i.e. {{value.Site}}, instead of just {{Site}} for example. This is the corresponding view:
class homeview(ListView):
template_name = 'annual_means/home.html'
def get_queryset(self):
return AnnualMean.objects.values("Site", "url").distinct()
What do I need to do to get the slice to work?
I think, what you need is this:
<table>
<tr>
<th>URL</th>
<th>SITE</th>
</tr>
{% for value in object_list %}
<tr>
<td>{{value.url}}</td>
<td>{{value.Site}}</td>
</tr>
{% endfor %}
</table>
URLs and Sites will be displayed as a table.

django template variable number of fields build of table from queryset

I'm trying to build a table in a template based on a variable number of fields.
The code I'm using is:
<table id="custom_report_table" class="display" width="100%">
<thead>
{% for field in fields %}
<th>{{ field }}</th>
{% endfor %}
</thead>
<tdody>
{% for CI in CIs %}
<tr>
<td>{{ CI }}</td>
</tr>
{% endfor %}
</tdody>
</table>
fields is a list with all the fields and CIs is a queryset with the data that needs to go into the table.
The problem is that I usually know the name of the fields so I can call each on individually when creating the cells in the usual way:
{{CI.field1}}
{{CI.field2}}
....
But now I can't hard code the fields' names as they are variable and come from the list.
Is there a way to do this?
Thanks,
Isaac
Just iterate again over CIs using items
{% for key,value in CIs.items %}
<td>{{ key }} {{value}}</td>
{%endof%}
If you only want to print items that are in fields:
{% for field_name, field_value in CIs.items %}
{% if field_name in fields %}
<th>{{ field_name }}</th>
<td>{{ field_value }}</td>
{% endif %}
{%endof%}
Solved by using .values in the queryset creation in the view.
And to reference the foreign keys for each field I had to build up the list of values with a list of field_name_foreign_field.
As the names for all foreign key fields followed a standard rule, it was quite easy with a for loop in the view.