Django- Json data in template - json

I am accessing an API and get JSON data. I can see that JSON is generated. However I am not able to show it in template.
Below is the sample Json data.
{
"response_code":1,
"response":{
"a":"01/07/2017",
"b":"12",
"c":"23",
"d":"34",
"e":"45",
"f":"56",
},
"error_code":null,
"error_message":null
}
I passed this data in view to template as dataset.
View as asked in comment.
response = requests.request("GET", url, data=payload, headers=headers, params=querystring)
json_string = json.dumps(response)
return render(request,'searchhome.html',{'dataset':json_string})
What I tried in template.
{% for key, value in dataset.items %}
{{key}}: {{value}}
{% endfor %}
Another try
{% for d in dataset %}
{% for key, value in d.response.items %}
{{key}} {{value}}
{% endfor %}
{% endfor %}
Template is not showing any error or any response. What I am doing wrong here?

To iterate, you need it to be a python dict object and not the JSON string.
You can do it using the json package.
Example:
import json
string_containing_json = ".."
data = json.loads(string_containing_json)
Json is just a string arranged in special format. You need to convert it to python objects before using it.
EDIT: I have no idea why the downvote. Judging from the question, this is definitely the issue here. The OP is not converting the json string into dictionary. You can't iterate over a string, like you do a dictionary.

You should not dump the data back to JSON in the view. Once you've done that, it's now a string, so it doesn't have an items method.
You should pass the result of response.json() directly to the template.

I think, within the view, you need to convert the response like this:
import json
response = requests.request("GET", url, data=payload, headers=headers, params=querystring)
json_string = json.dumps(response)
return render(request,'searchhome.html',{'dataset':json_string})
And then, I think, you can access the data as
{{ dataset.response_code }}
{{ dataset.response.0 }}
etc

Finally I could solve it.
My changed view:
response = requests.request("GET", url, data=payload, headers=headers, params=querystring)
response = json.loads(response.content)
json_string = response["response"]
return render(request,'searchhome.html',{'dataset':json_string})
My Template
{% for k,v in dataset.items %}
<tr>
<td>
{{k}}:{{v}}</td>
<tr>
{% endfor %}
Solution came with trying all answers posted and just adding .content to json.loads(response)

Related

Why is there no output in jinja2 Loop?

i try to loop over a dic in my jinja template. But i always get no output.
dic={"SERVICE1" : "tess","SERVICE2" : "test"}
with open(Path(Path.cwd()/"test.jinja")) as f:
template = Template(f.read()).render(data_nebula_docker)
print(template)
My template looks like this:
{% for item in dic %}
{{item}}
{% endfor %}
Normal Variablse are working fine. Does i have some basic misunderstanding?
Thx for your help!
There are a couple of problems with your code. I'm going to assume the indentation issue in your with statement is just a copy-and-paste error, and that your code actually looks like:
with open(Path(Path.cwd()/"test.jinja")) as f:
template = Template(f.read()).render(data_nebula_docker)
print(template)
In your template you're referencing a variable dic, but you aren't passing this to the render method. You want:
from jinja2 import Template
from pathlib import Path
dic = {"SERVICE1": "tess", "SERVICE2": "test"}
with open(Path(Path.cwd() / "test.jinja")) as f:
template = Template(f.read()).render(dic=dic)
print(template)
Which produces:
SERVICE1
SERVICE2
You'll note that this only prints out the keys in your dictionary. When you iterate over a dictionary (in Jinja or Python), you get a list of keys. If you want (key, value) tuples instead, use the .items() method:
{% for item in dic.items() %}
{{item}}
{% endfor %}
Which produces:
('SERVICE1', 'tess')
('SERVICE2', 'test')
Separately, your use of pathlib.Path is a little convoluted; you can write instead:
with (Path.cwd()/"test.jinja").open() as f:
In the above:
It's not necessary to wrap the result of Path() / "string" in a call to Path() (because it's already a Path)
A Path object has an open method, so we can call .open() on the Path that results from Path.cwd()/"test.jinja".
Although in this case, your pathlib based code isn't much of a win over:
with open("test.jinja") as f:

Display Twig variable using JSON.stringify

I have a function in a Silex application that executes a cURL statement and returns JSON string which is assigned to the variable curl_result. This variable is then passed into a Twig template like this:
return $twig->render('http.html.twig', ['curl_result' => $result]);
In the Twig template, I am able to display the JSON string variable by using this:
{% if curl_result is defined %}
<pre>{{ curl_result }}</pre>
{% endif %}
which produces this result:
{"ServiceAccount":[{"Type":"MATTER","ID":[{"body":"1980933400...
Alternatively, when I use JSON_PRETTY_PRINT:
{% if curl_result is defined %}
<pre>{{ curl_result|json_encode(constant('JSON_PRETTY_PRINT')) }}</pre>
{% endif %}
the only effect seems to be that it places the JSON string within double-quotes, and escapes the inside double-quotes:
"{\"ServiceAccount\":[{\"Type\":\"MATTER\",\"ID\":[{\"body\":\"1980933400...
Neither of these displays the JSON in a usable manner. I want the JSON to be displayed in a human readable format and would like to use JSON.stringify for that purpose. I am able to use the following javascript code and JSON.stringify some random text like this:
<script>
var jsonString = '{"some":"json"}';
var jsonPretty = JSON.stringify(JSON.parse(jsonString),null,2);
output(jsonPretty);
</script>
If you're still with me after all that, here's my question: How do I bring the Twig variable curl_result into javascript so that I can JSON.stringify it?
In your controller $result is a string, it contains a JSON string but at this point it is only a string. So when you pass it to json_encode it escapes all double quotes because it wants to encode a simple string.
If you want to use json_encode to pretty print this data, you first need to decode this string (exactly what you did in your alternative solution with JSON.parse), then encode it with pretty print option. So in your controller you should have this change:
return $twig->render('http.html.twig', ['curl_result' => json_decode($result)]);
You can then use json_encode to pretty print the curl_result in your twig file the exact way you tried in your second twig snippet:
{% if curl_result is defined %}
<pre>{{ curl_result|json_encode(constant('JSON_PRETTY_PRINT')) }}</pre>
{% endif %}
Alternatively, you can print $result as a JS variable in your twig template file like this:
<script>
var jsonString = '{{ curl_result | raw }}';
var jsonPretty = JSON.stringify(JSON.parse(jsonString),null,2);
console.log(jsonPretty);
</script>
Please note the use of raw filter when printing the json string.

Dotliquid JSON Transformation using JSON.net

Im interested in performing JSON transformations and looked into using dotliquid.
In order to avoid having a POCO for the input JSON just to be able to send it as a variable, I would like to send the deserialised JSON. From my understanding, we can't send dynamic to render method, and JObject or JArray does not work as expected. I Tried deserialising to Dictionary< string, object>, but that could not handle nested JSON structures.
liquid
[
{%- for p in data.names -%}
{
"name" : {{ p.name }}
} {%- unless forloop.Last == true -%},{% endunless %}
{%- endfor -%}
]
C# code
Template template = Template.Parse(File.ReadAllText("Maps/account.liquid"));
var json = JsonConvert.DeserializeObject<Dictionary<string, object>>(
#"{ ""names"":[{""name"": ""John""},{""name"":""Doe""}] }");
var jsonHash = Hash.FromAnonymousObject(new { Data = json});
Output
[
{
"name" :
},
{
"name" :
}
]
I know that Microsoft Logic Apps has implemented a similar feature using dotliquid. https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-enterprise-integration-liquid-transform
What different ways are there? Do I need to parse the JObject/JArray to a nested Dictionary, or what alternatives are there?
You can get it to work using the DictionaryConverter from Deserialize JSON recursively to IDictionary<string,object> and Hash.FromDictionary
var json = JsonConvert.DeserializeObject<IDictionary<string, object>>(#"{ ""names"":[{""name"": ""John""},{""name"":""Doe""}] }", new DictionaryConverter());
var jsonHash = Hash.FromDictionary(json);
var templatetest = "<h1>{{device}}</h1><h2>{{speed}}</h2>{% for client in names %}<h4>{{client.name}}</h4>{% endfor %}";
var template = Template.Parse(templatetest);
var render = template.Render(jsonHash);

Send array list to Twig View without headers in Symfony 2

I need help sending query list to Twig without headers. I have already query my data and I am stuck. I had to have this data in JSON structure.
This is name of my root: 'AdminBundle:Note:viewPdf.html.twig'
And here is name of query class in propel - it is empty now: MnNoteCommentQuery.
Here is my code:
$noteQuery = MnNoteCommentQuery::create()->find();
$responsed = new JSonResponse($noteQuery);
return $this->render('AdminBundle:Note:viewPdf.html.twig', array('notes' => $responsed));
Just use json_encode in twig
return $this->render('AdminBundle:Note:viewPdf.html.twig', array('notes' => $notes));
Twig:
{{ notes | json_encode() }}
You can customize json representation by implementing JsonSerializable interface

golang template with multiple structs

I have struct that has JSON field something like this:
detail := &Detail{
Name string
Detail json.RawMessage
}
template looks like this:
detail = At {{Name}} {{CreatedAt}} {{UpdatedAt}}
My question can we use one or more structs for a single template or it is restricted to only one struct.
You can pass as many things as you like. You haven't provided much of an example to work with, so I'm going to assume a few things, but here's how you would tackle it:
// Shorthand - useful!
type M map[string]interface
func SomeHandler(w http.ResponseWriter, r *http.Request) {
detail := Detail{}
// From a DB, or API response, etc.
populateDetail(&detail)
user := User{}
populateUser(&user)
// Get a session, set headers, etc.
// Assuming tmpl is already a defined *template.Template
tmpl.RenderTemplate(w, "index.tmpl", M{
// We can pass as many things as we like
"detail": detail,
"profile": user,
"status": "", // Just an example
}
}
... and our template:
<!DOCTYPE html>
<html>
<body>
// Using "with"
{{ with .detail }}
{{ .Name }}
{{ .CreatedAt }}
{{ .UpdatedAt }}
{{ end }}
// ... or the fully-qualified way
// User has fields "Name", "Email", "Address". We'll use just two.
Hi there, {{ .profile.Name }}!
Logged in as {{ .profile.Email }}
</body>
</html>
Hope that clarifies.