my python code:
def index(request):
body=list(Body.objects.all())
loads=list(Load.objects.all().order_by('length'))
badLoads=[]
goodLoads=[]
for load in loads:
if load.length>body[0].length or load.width>body[0].width or load.mass>body[0].mass:
badLoads.append(load)
else:
goodLoads.append(load)
goodLoadsLength=len(goodLoads)
context={
'body':body[0],
'loads':loads,
'badLoads':badLoads,
'goodLoads':goodLoads,
'goodLoadsLength':goodLoadsLength,
}
return render(request,'index.html',context)
html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div>
{% if body %}
<p>body length: {{ body.length }}, body width: {{ body.width }}, body height: {{ body.height }}, body max mass, which can be taken: {{ body.mass }}</p>
{% else %}
<p>No parameters found</p>
{% endif %}
</div>
<div>
{% if loads %}
<ul>
{% for load in loads %}
<li>load id: {{ load.id }}, load length:{{ load.length }}, load width: {{load.width}}, load height: {{load.height}}, load mass: {{load.mass}}</li>
{% endfor %}
</ul>
{% else %}
<p>No loads are available.</p>
{% endif %}
</div>
<div>
{% if goodLoads %}
<ul>
{% for goodLoad in goodLoads %}
<li>load id: {{ goodLoad.id }}, load length:{{ goodLoad.length }}, load width: {{goodLoad.width}}, load height: {{goodLoad.height}}, load mass: {{goodLoad.mass}}</li>
{% endfor %}
</ul>
{% else %}
<p>No loads are available.</p>
{% endif %}
</div>
<div>
{% if loads %}
<ul>
{% for badLoad in badLoads %}
<li>load id: {{ badLoad.id }}, load length:{{ badLoad.length }}, load width: {{badLoad.width}}, load height: {{badLoad.height}}, load mass: {{badLoad.mass}}</li>
{% endfor %}
</ul>
{% else %}
<p>No loads are available.</p>
{% endif %}
</div>
<script>
const loadsLength="{{goodLoadsLength}}";
const goodLoads="{{goodLoads}}"
</script>
</body>
</html>
I would like to do a simple table with the help of javascript on the same page. I know I can do a table through html, but I would like to do it through Javascript, on the same page. But somehow I can see in script simple variables, like this one:
const loadsLength="{{goodLoadsLength}}";
But I cannot do list of items. The number of items can be different. So it should be going through for or forEach loop, but script does not give me any chance to get the members of a list in case of python(or array in case of javascript) into javascript block. If I try:
const goodLoads="{{goodLoads}}";
console.log(goodLoads);
It gives me:
[<Load: Load object (1)>]
Which seems like it sees the object in array. But when I try:
console.log(goodLoads[0].length);
or
foodLoads.forEach(item=>{
console.log(item.length)
})
It gives me: the object is undefined. I tried couple of more approaches like with for loop with for object in objects, or normal for loops with the step way. But the object is undefined.
I guess I don't understand how to get the list/array from html to script block. It should be seen as normal array of items. But I cannot get them. Can somebody pinpoint me to the answer? Thank you.
CodePudding user response:
Use the Django built-in json_script
(see documentation here) template tag to safely output a python object as JSON wrapped in a script tag. Then in your main JS script, you can parse the JSON object and do all standard operations with it.
In your template:
{{ goodLoads|json_script:"goodLoads"}}
In your main JS file:
let goodLoads = JSON.parse(document.getElementById('goodLoads').textContent);
Another issue is that you're passing QuerySet objects into the context variable goodLoads. It won't be very useful to have those objects in your JS file, because you cannot access the object field values. For that turn the QuerySet object into a dict before passing it to the context.
For example using queryset.values(),
def index(request):
body=list(Body.objects.all())
loads=list(Load.objects.all().order_by('length'))
badLoads=[]
goodLoads=[]
for load in loads:
if load.length>body[0].length or load.width>body[0].width or load.mass>body[0].mass:
badLoads.append(load.values()) #converting to dict here
else:
goodLoads.append(load.values()) #converting to dict here
goodLoadsLength=len(goodLoads)
context={
'body':body[0],
'loads':loads,
'badLoads':badLoads,
'goodLoads':goodLoads,
'goodLoadsLength':goodLoadsLength,
}
return render(request,'index.html',context)