问题
Hi I would like to create table using JS datatables library.
I got problem when passing value in template to js script. I created JSON object from my table which I want to display. It's passed correctly to template, when I display it everything is fine, but when trying to pass it to script nothing happend and I got empty table.
Thats the way I do it:
class VotesList(generic.ListView):
model = Vote
template_name = 'votes-list.html'
def get_context_data(self, **kwargs):
votes = Vote.objects.all().values('user', 'group', 'council')
votes_json = json.dumps(list(votes))
context = super(VotesList, self).get_context_data(**kwargs)
context['orderby'] = self.request.GET.get('orderby', 'created_date')
context['json_data'] = votes_json
return context
template:
{% block javascript %}
{% load static %}
<script type="text/javascript">
$(document).ready(function() {
var json=JSON.parse('{{ json_data | safe }}');
$('#votes_list').DataTable({
data: json,
columns:[
{ title: "user" },
{ title: "group" },
{ title: "council" }]
} );
};
</script>
{% endblock %}
{% block content %}
<p>{{ json_data | safe }}</p> <<< here data is printed fine
{% if vote_list %}
<table id="votes_list" class="display", style="width:100%">
<thead>
<tr>
<th>Właściciel</th>
<th>Grupa</th>
<th>Rada</th>
</tr>
</thead>
</table>
{% else %}
<p>Brak głosowań!</p>
{% endif %}
{% endblock %}
and output data looks like that:
[{"user": 2, "group": 1, "council": 1}, {"user": 2, "group": 2, "council": 1}, {"user": 3, "group": 1, "council": 1}, {"user": 2, "group": 1, "council": 1}, {"user": 2, "group": 2, "council": 2}, {"user": 1, "group": 1, "council": 2}, {"user": 3, "group": 1, "council": 1}, {"user": 2, "group": 1, "council": 1}, {"user": 1, "group": 1, "council": 2}, {"user": 1, "group": 2, "council": 1}, {"user": 1, "group": 1, "council": 1}, {"user": 1, "group": 1, "council": 1}]
My second question is about something else: I'm storing lot of information as choices:
STATUS_INACTIVE = 0
STATUS_ACTIVE = 1
STATUS_FINISHED = 2
STATUS_CHOICES = (
(STATUS_INACTIVE, 'Inactive'),
(STATUS_ACTIVE, 'Active'),
(STATUS_FINISHED, 'Finished'),
)
How to pass not numbers but this human readable values ('Inactive') to JSON above?
回答1:
For 1st question, try adding <tbody></tbody>
after </thead>
tag. Rerun the code.
For DataTables to be able to enhance an HTML table, the table must be valid, well formatted HTML, with a header (thead) and a single body (tbody).
There is another simpler way to render datatable.
views.py -
context['json_data'] = votes # no need to use json.dumps
In html-
<table id="votes_list" class="display", style="width:100%">
<thead>
<tr>
<th>Właściciel</th>
<th>Grupa</th>
<th>Rada</th>
</tr>
</thead>
<tbody>
{% for data in json_data %}
<tr>{{ data.user }}</tr>
<tr>{{ data.group }} </tr>
<tr>{{ data.council }} </tr>
{% endfor %}
</tbody>
</table>
<script type="text/javascript">
$(document).ready(function() {
$('#votes_list').DataTable();
}
</script>
For 2nd question -
{% if data.user == 1 %}
Active
{% elif data.user == 2%}
Inactive
{% else %}
Finished
{% endif %}
OR
{% if data.group == 1 %}
{{ status_dict.0 }}
{% elif data.group == 2%}
{{ status_dict.1 }}
{% else %}
{{ status_dict.2 }}
{% endif %}
>>>status_dict = dict(STATUS_CHOICES)
{0: 'Inactive', 1: 'Active', 2: 'Finished'}
In datatable - you can apply the same logic. for example-
"columns": [
{ "data": "engine" },
{ "data": "browser" },
{
"data": "platform",
"render": function(data, type, row, meta) {
if(true)
return “display this”
};
return “false"
}
]
回答2:
if you pass your data in your views like this
class VotesList(generic.ListView):
model = Vote
template_name = 'votes-list.html'
def get_context_data(self, **kwargs):
context = super(VotesList, self).get_context_data(**kwargs)
context['votes'] = Vote.objects.all()
return context
Then in your template you could have
{% block javascript %}
{% load static %}
<script type="text/javascript">
$(document).ready(function() {
$('#votes_list').DataTable({
});
});
</script>
{% endblock %}
{% block content %}
{% if vote_list %}
<table id="votes_list" class="display", style="width:100%">
<thead>
<th>Właściciel</th>
<th>Grupa</th>
<th>Rada</th>
</thead>
<tbody>
{% for vote in votes %}
<tr>
<td>{{ vote.user }}</td>
<td>{{ vote.group}}</td>
<td>{{ vote.countcil }}</td>
<tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>Brak głosowań!</p>
{% endif %}
{% endblock %}
It should render as a JS Datatable
回答3:
For your first question, I would store your your template variable in a javascript variable like so var data = "{{ template_var }}"
and then use that new variable where you are trying to use it now. Then you should be able to handle what you are trying to do.
Mind you other answers will tell you to just create a table, but I know you are using DataTables and in addition if you have over 50 objects you are trying to load in the table you may run into problems of loading speed. So, it may be good to do what you are doing and this will allow you to AJAX and retrieve the next set of data working with pagination. This is something that can be addressed for future proofing an application.
来源:https://stackoverflow.com/questions/51408948/passing-django-template-variables-to-js-datatables