Load JSON from Django Variable (Ajax)
Load JSON from Django Variable (Ajax)
Hi All,
I've been trying to get my DataTable to load data using Ajax and I haven't been able to get the JSON loaded from my Django variable into the DataTable, despite validation that the JSON is correctly formatted. I had originally gotten the table running without Ajax, loading the data through django variable loops, but I want to implement Ajax to use data loading functionalities for large sets of data etc.
Here is the script / html:
<table id="test_table" class="display table table-striped table-bordered" border="1" cellspacing="0" width="100%">
<thead>
<tr>
<th>First</th>
<th>Last</th>
<th>Num.</th>
</tr>
</thead>
</table>
<script type="text/javascript">
$(document).ready(function() {
var json={{ test_data | safe }}
var data= json["data"]
var json2 = JSON.stringify(data)
window.alert(json2)
$('#test_table').DataTable({
"ajax": json2
} );
});
</script>
The JSON for json2 is the following:
[{
"first_name": "John",
"last_name": "Smith",
"number": "12345"
}, {
"first_name": "Alex",
"last_name": "Smith",
"number": "122345"
}, {
"first_name": "John",
"last_name": "Smith",
"number": "12345"
}, {
"first_name": "Alex",
"last_name": "Smith",
"number": "122345"
}]
Here is my view for the data:
def test_data(request):
test_all = TestData.objects.all().values('first_name', 'last_name', 'number')
test_all = json.dumps({"data": list(test_all)})
data = {'test_data': test_all,}
return render(request, 'test.html', data)
Might anyone be able to help here? I've tried implementing the dataTable with ajax using a few methods ("data" field and "column" values, etc.), but I always hit the blocker message DataTables warning: table id=test_table - Invalid JSON response
and the dev tools don't give me a reason as to why the JSON didn't load. The ultimate goal is to be able to use server side processing (to enable deferLoading etc.)
Thank you so much!
Answers
.
Since you are using an array of objects you need to use
columns.data
to define your Datatables data structure.Kevin
Hi Kevin, thank you for the response! My initial attempt was using columns.data, however I was receiving the same error mentioned (DataTables warning: table id=test_table - Invalid JSON response).
For example, using the following format:
I receive the error and when looking at dev tools, the output request URL is > > > `
I'm not sure I understand the encoded data URL?
I also implemented the columns.render option, and received the same encoded URL results.
Am I missing something simple?
Best,
Alex
It looks like you are not returning the JSON in an object called
data
which is the default Datatables looks for. In that case you would useajax.dataSrc
.The second example on the doc page is what I think you will want to use.
It looks like your JSON string is escaped. I've had that problem when I double encode the data into JSON. For example the AJAX called function calls another which encodes the return as JSON. Then the original function encodes that same data as JSON which results in an escaped string.
Kevin
Hi Kevin, thanks for getting back to me again. With regards to the JSON encoding, is the only solution to rework how the data is sent from the Django view linked above to the page maybe, or can decoding be executed in the html script? Unescaping functions didn't result in any changes, also after implementing ajax.dataSrc - and parsing simply returned [Object object] for each entry which doesn't help. How were you able to fix it?
Thanks!
Alex
In Python I use
json.dumps(data)
for the response data. Not sure if its the same in Django. Just make sure you are doing this only once in your Django code.If you want you can post your Django code and I'll take a look but I don't use Django but do use Python and Cherrypy.
Kevin
Hi Kevin,
Thanks for confirming that - I am doing the same thing. The views file function linked below is what grabs the data from the DB, puts it into the variable 'data', which I access in the html page file seen below:
Views function that generates variable to be accessed on page:
Current dataTable example using the variable outputted from above:
Data in the variable json2:
Thanks!
Alex
I think its becoming more clear - sorry a bit slow on this one I'm assuming you are still having the same invalid JSON response error.
Your AJAX URL is "json2" which is a Javascript variable. That won't work. AJAX is expecting to send an HTTP request and receiving a response containing the JSON data. I'm not sure what this line is actually doing
var json={{ test_data | safe }}
but I'm guessing its a Django way to call your test_data() function and assign the value to the variable "json".The little bit of Django docs I looked at indicate the third parameter in the Django render() function is a dictionary. Didn't see reference to this but I suspect that Django will automatically convert the dict to JSON and return to the web page. If this is the case then your "test_all" data is converted to JSON twice, which I think is the problem, and you will want to remove the
json.dumps()
function call. I'm thinking you will want your Django function to look like this:This assumes render() will convert the dictionary to JSON.
Since it seems that "json" is receiving the response from test_data() it might be easier to use Datatables
data
option rather thenajax
. If my above assumptions are correct then I think you should change you JS code to look like this:I wonder if this would work:
Let us know the results.
Kevin
Hi Kevin,
No worries at all - I really appreciate the help here! So you are correct about the django behavior - the function returns a dictionary that I can access through the following variable : {{ test_data | safe }}
I played around with your suggestions, and you were definitely correct - I was encoding the JSON twice. I ended up just using json.dumps in the django function:
and your suggested javascript without another json encoding:
and I am now seeing data load!
My last question here is that my initial goal was to be able to load a large set of data, one column containing images, using deferLoading (which I understand uses the serverSide variable). I also thought using the function above
data: json.data
does not allow this - in testing it was non-functional as well. What is my best bet for next steps forward?Thank you so much for your help again.
Best,
Alex
Enabling server side processing moves the client side features like searching and sorting to the server script. Your Python scripts will need to support the parameters sent to the server then query the DB using things like LIMIT and OFFSET to retrieve and respond with a page worth of data. This happens for each draw of the table (search, sort, page, etc). The server side processing explains this.
Yes, you will need the
ajax
option for server side processing. Did you try the second JS option using ajax?The
deferRender
option might be a good option for you to stay with client side processing. Take a look at this FAQ. If you are going to usecolumns.render
to display images, etc you will want to make sure you only render for the "display" type. The orthogonal data doc explains the different types.Stick with client side processing if you can. Its much simpler.
Kevin