32👍
Ok, I found the solution!
Mostly it was because of not quoting the results. When Javascript was trying to parse the object this wasn’t recognized as string.
So, first step is:
var js_list = {{django_list}};
changed to:
var js_list = "{{django_list}}";
After this I realized that Django was escaping characters so I had to replace them like this:
var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : '<',
g : '>',
quo : '"'
}[b];
}));
myData = JSON.parse( myJSONList );
Note: I tried to avoid escaping characters from Django using this:
var js_list = "{{json_list|safe}}";
But this doesn’t work because it gets confused with the quotes.
Finally I found a way to avoid the logic on the backend of converting to JSON before sending it to Javascript:
var myDjangoList = (("{{django_list |safe}}").replace(/&(l|g|quo)t;/g, function(a,b){
return {
l : '<',
g : '>',
quo : '"'
}[b];
}));
myDjangoList = myDjangoList.replace(/u'/g, '\'')
myDjangoList = myDjangoList.replace(/'/g, '\"')
myData = JSON.parse( myDjangoList );
I’m sure this can be improved, I let this to you 😉
Thanks for your answers
Hope it helps to someone else!
35👍
Same Question, “Better”(more recent) answer: Django Queryset to dict for use in json
Answer by vashishtha-jogi:
A better approach is to use DjangoJSONEncoder. It has support for Decimal.
import json from django.core.serializers.json import DjangoJSONEncoder prices = Price.objects.filter(product=product).values_list('price','valid_from') prices_json = json.dumps(list(prices), cls=DjangoJSONEncoder)
Very easy to use. No jumping through hoops for converting individual
fields to float.Update : Changed the answer to use builtin json instead of simplejson.
This is answer came up so often in my google searches and has so many views, that it seems like a good idea to update it and save anyone else from digging through SO. Assumes Django 1.5
.
- [Django]-Django class-based view: How do I pass additional parameters to the as_view method?
- [Django]-CORS: Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true
- [Django]-Django – Model graphic representation (ERD)
10👍
Django querysets are serializable by JSON. Some field types (such as date, apparently), can’t be serialized at is. A workaround for date objects is posted in another question on JSON and Python.
I would recommend creating dictionaries directly in the JavaScript itself. Given models like this:
class Article(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField()
content = models.TextField()
class Author(models.Model):
article = models.ForeignKey("Article", related_name="authors")
first_name=models.CharField(max_length=100)
last_name=models.CharField(max_length=100)
I’d do something like this in the template:
<script type="text/javascript">
var articles = [
{% for article in article_list %}
{% if not forloop.first %},{% endif %}
{
title: "{{ article.title }}",
slug: "{{ article.slug }}",
content: "{{ article.content }}",
authors: [
{% for author in article.authors.all %}
{% if not forloop.first %},{% endif %}
{
first_name: "{{ author.first_name }}",
last_name: "{{ author.last_name }}",
}
{% endfor %}
]
}
{% endfor %}
]
</script>
If you maybe worded the question a little poorly and aren’t planning on inserting code in a <script>
tag and actually need JSON for some reason, I’d simply do a loop in the view and create a list of dict
s, which JSON has no problem serializing, and JavaScript no problem in understanding.
- [Django]-Django: Where to put helper functions?
- [Django]-Why am I getting this error in Django?
- [Django]-Row level permissions in django
8👍
EDIT: please don’t use this method, see @agconti’s answer.
Use the escapejs filter: https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#escapejs
Example of dumping a list:
var foo = [{% for x in y %}'{{ x|escapejs }}',{% endfor %}]
- [Django]-Pylint "unresolved import" error in Visual Studio Code
- [Django]-Celery. Decrease number of processes
- [Django]-Django 1.8 KeyError: 'manager' on relationship
7👍
Since Django 2.1 there is the json-script template tag. From the docs:
json_script
Safely outputs a Python object as JSON, wrapped in a tag,
ready for use with JavaScript.Argument: HTML “id” of the tag.
For example:
{{ value|json_script:"hello-data" }}
If value is the dictionary
{'hello': 'world'}
, the output will be:<script id="hello-data" type="application/json"> {"hello": "world"} </script>
The resulting data can be accessed in JavaScript
like this:var value = JSON.parse(document.getElementById('hello-data').textContent);
XSS attacks are mitigated by escaping the characters “<”, “>” and “&”. For
example if value is{'hello': 'world</script>&'}
, the output is:<script id="hello-data" type="application/json"> {"hello": "world\\u003C/script\\u003E\\u0026amp;"} </script>
This is compatible
with a strict Content Security Policy that prohibits in-page script
execution. It also maintains a clean separation between passive data
and executable code.
- [Django]-Using a UUID as a primary key in Django models (generic relations impact)
- [Django]-Django's ModelForm unique_together validation
- [Django]-How to read the database table name of a Model instance?
6👍
- [Django]-How can I get tox and poetry to work together to support testing multiple versions of a Python dependency?
- [Django]-PicklingError: Can't pickle <class 'decimal.Decimal'>: it's not the same object as decimal.Decimal
- [Django]-When to use get, get_queryset, get_context_data in Django?
4👍
Your problem is that, as so often, your requirements are under-specified. What exactly do you want the JSON to look like? You say you want to “serialize the queryset”, but in what format? Do you want all the fields from each model instance, a selection, or just the unicode representation? When you’ve answered that question, you’ll know how to solve your problem.
One approach, for example, might be to use the values
queryset method to output a dictionary of fields for each instance, and serialize that (you need to convert it to a list first):
data = SomeObject.objects.values('field1', 'field2', 'field3')
serialized_data = simplejson.dumps(list(data))
- [Django]-Django – how to create a file and save it to a model's FileField?
- [Django]-Assign variables to child template in {% include %} tag Django
- [Django]-Attempt to write a readonly database – Django w/ SELinux error
4👍
You have to mark the string as safe to be sure it’s not escaped.
in one of my project I use it like this:
# app/templatetag/jsonify.py
from django import template
from django.utils.safestring import mark_safe
import json
register = template.Library()
@register.filter
def jsonify(list):
return mark_safe(json.dumps(list))
and in the template
{% load jsonify %}
<script type="text/javascript" >
var js_list = {{ python_list|jsonify|escapejs }};
</script>
but you may prefer to just add mark_safe or use |safe in the template to avoid all >
stuff
If the problem is for handling complex python object you may have to do your handler like this: JSON datetime between Python and JavaScript
- [Django]-ImportError: cannot import name '…' from partially initialized module '…' (most likely due to a circular import)
- [Django]-Django Admin: OneToOne Relation as an Inline?
- [Django]-How can I auto-populate a PDF form in Django/Python?
3👍
Django offers in-built help for the very scenario you are trying to do here. It goes something like this:
You have a python sequence, list, dictionary, etc in your view, let’s call it py_object
. One approach is to jsonify it before passing it to the rendering engine.
from django.shortcuts import render_to_response
import json
Then later on use like this…
render_to_response('mypage.html',{'js_object':json.dumps(py_object)})
In you template, then use the safe
filter to import the already jsonized object from python into javascript, like this…
data = {{ js_object|safe }}
That should solve your problem i hope.
- [Django]-Django-Forms with json fields
- [Django]-Django DateField default options
- [Django]-Django manage.py runserver invalid syntax
1👍
either;
read object using {{ django_list }}
and then remove unwanted characters
or do;
{{ django_list | safe}}
- [Django]-Django : Testing if the page has redirected to the desired url
- [Django]-Django – convert a list back to a queryset
- [Django]-Change model class name in Django admin interface
0👍
Consolidated answer (my env: Django 2.0)
In views.py
import json
data= []
// fil the list
context['mydata'] = json.dumps({'data':data})
In template
<script type="text/javascript">
var mydataString = "{{mydata|escapejs}}";
console.log(JSON.parse(mydataString));
</script>
- [Django]-How can I enable CORS on Django REST Framework
- [Django]-Django migrate –fake and –fake-initial explained
- [Django]-Django queries: how to filter objects to exclude id which is in a list?
0👍
For me to send the whole QuerySet (while preserving the fields names; sending object
not list
). I used the following
# views.py
units = Unit.objects.all()
units_serialized = serializers.serialize('json', units)
context['units'] = units_serialized
and just use safe
tag in the template
# template.html
<script>
console.log({{units|safe}});
</script>
- [Django]-Django Multiple Authentication Backend for one project
- [Django]-How to use permission_required decorators on django class-based views
- [Django]-IntegrityError duplicate key value violates unique constraint – django/postgres
0👍
NOTE for django 2.1
i found this a little confusing on django documentation so simply explaining a little bit easy way.
we would normally use this like
{{ my_info }}
or loop over it depending on what we needed. But if we use the following filter,
json_script
we can safely output this value as JSON
{{ my_info|json_script:"my-info" }}
Our data has been added as JSON, wrapped in a script tag, and we can see the data. We can now use this value by looking it up in JavaScript like so:
info = JSON.parse(document.getElementById('my-info').textContent);
- [Django]-How to force application version on AWS Elastic Beanstalk
- [Django]-How can I filter a Django query with a list of values?
- [Django]-How do I create sub-applications in Django?
0👍
Be careful on also making sure that you output JSON data correctly from Django, otherwise all trials on the frontend side will be a waste of time. In my case I could not use JsonResponse as part of the render function so I did the following:
def view(self, request):
data = []
machine_data = list(Machine.objects.filter(location__isnull=False).values_list('serial', 'location', 'customer__name'))
data.append({
"locations": machine_data,
})
return render(request, 'admin/company/device/map.html', {
"machines": data
})
And on the frontend:
{% block content %}
{{ machines_with_location|json_script:"machineLocationData" }}
<div id="content-main">
<h1>Title</h1>
<script type="text/javascript">
const locationDataFromJson = JSON.parse(document.getElementById('machineLocationData').textContent);
</script>
</div>
{% endblock %}
- [Django]-Django queryset filter – Q() | VS __in
- [Django]-How to write django test meant to fail?
- [Django]-POST jQuery array to Django