'How to pass a queryset from django to javascript function?
I want to pass a queryset from a view to a javascript function throught the template:
my view.py
:
def myview(request):
lista=Mymodel.objects.filter(tipo=mytipo)
context_dict['lista']=lista
return render(request, 'mytemplate.html', context_dict)
my template.html
:
<script>
<!--
window.onpageshow = function() {
myfunction('{{lista}}');
};
-->
</script>
my javascript.js
:
function myfunction(lista) {
for (i=0; i<lista.length; i++) {
console.log(lista[i].name)
}
}
The problem is that lista
become a string. I tried with JSONEncoder but i'm not sure how to use. I would like to avoid JsonResponse because I want to use that view for my template (if possible).
Edit:
There's a problem with the solution proposed in the answer:
TypeError: Python object is not JSON serializable
and the solution proposed in this link doesn't works either (can't find _meta
attribute called by model_to_dict
).
JSON.parse doesn't works
SyntaxError: missing ) after argument list
and the problem seem to be between one path and the other:
myfunction(JSON.parse('['/mypath/myimage.png', '/otherpath/otherimage.png', 'etc... ']'));
Also in the template you must add |safe
.
Luckly I need a list of string so:
my view.py
:
def myview(request):
lista=Mymodel.objects.filter(tipo=mytipo)
lista_formatted=[]
for elem in lista:
lista_formatted.append('/media/'+str(elem.myfield))
lista_formatted=json.dumps(lista_formatted)
context_dict['lista']=lista_formatted
return render(request, 'mytemplate.html', context_dict)
my template.html
:
<script>
<!--
window.onpageshow = function() {
myfunction({{lista|safe}});
};
-->
</script>
Solution 1:[1]
change the line below
context_dict['lista']=json.dumps(lista) //note json.dumps() wraps it
Remove the quotes around here:
<script>
<!--
window.onpageshow = function() {
myfunction({{lista}});//<--quote removed!
};
-->
</script>
Solution 2:[2]
You need to first pass a queryset as a list of dictionary representing instances to the template. In order to do so in the views.py
:
def myview(request):
lista = Mymodel.objects.filter(tipo=mytipo)
context_dict['lista'] = list(lista.values())
# Also you can instead also pass the needed parameters to 'values' function, like this:
# context_dict['lista'] = list(lista.values('field1', 'field3'))
return render(request, 'mytemplate.html', context_dict)
Then you need to define a js variable in the template and pass the value of lista
to it. So in the mytemplate.html
file:
<script>
window.onpageshow = function() {
myfunction({{ lista|safe }}); <!-- Don't forget to use 'safe' templatetag! -->
};
</script>
This way you don't need to use any third-party package.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | kennasoft |
Solution 2 | Hamidreza |