Django download return - json

simple question please, my POST in the views returns a json format dictionary
nested_data = {
'name': cleaned_data3['theme_name'],
'visualStyles': {
'barChart': {
'*': {
'general': [{
'responsive': cleaned_data2['responsive'],
'keepLayerOrder': cleaned_data2['maintain_layer_order']
}],
'legend': [{
'show': cleaned_data['show'],
'position': cleaned_data['position'],
'showTitle': cleaned_data['show_title'],
'labelColor': {
'solid': {
'color': '#666666'
}
},
'fontFamily': cleaned_data['font'],
'fontSize': cleaned_data['font_size']
}],
}
}
}
}
then I am returning the code formatted into json using:
return JsonResponse(nested_data)
This shows me the json rendered in the browser, but how do I download this return? In my index.html the submit button is rendering the return from the view, but I need to submit the forms and to download the content into .json file, something needs to be put into the href?
<input type="submit" value="Submit">
<a href="{{ xxx }}" download>DOWNLOAD</a>

You need change the response content type to application/force-download.
response = JsonResponse(nested_data)
response['Content-Type'] = 'application/force-download'
return response
# or ...
return HttpResponse(
simplejson.dumps(nested_data),
content_type='application/force-download'
)

You should define a function to write the json in views.py or index.html.
with open(file_name, "wb") as f:
f.write(data)
if you gonna write it in views.py, you could write the bellow lines in the js code section.
csrfmiddlewaretoken: "{{ csrf_token }}"

Related

How to display Markdown files containing HTML syntax in Gatsby?

I am using Markdown file to generate pages for gatby. In order to control the style of pictures, I use html syntax. However, the page generated by gatsby does not display the html part.
This is my markdown file:
---
......frontmatter......
---
......content......
<table>
<tr>
<td><img src="./images/2018/zotero/ZoteroWebDAV.png"></td>
<td><img src="./images/2018/zotero/ZoteroExts.png" width=100%></td>
</tr>
</table>
......content......
Everything else is rendered normally, however, neither the table nor the pictures in it are displayed. Here is my gatsby-config.js.
{
resolve: `gatsby-transformer-remark`,
options: {
excerpt_separator: `<!-- endexcerpt -->`,
plugins: [
// 'gatsby-remark-relative-images',
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 1200,
},
},
{
resolve: `gatsby-remark-image-attributes`,
options: {
dataAttributes: true
}
},
],
},
},
What can I do to make the html part in Markdown render normally?
You can use as well the built-in dangerouslySetInnerHtml property or any markdown parser like markdown-to-jsx.
Using the first approach, following Gatsby's guides:
import React from "react"
import { graphql } from "gatsby"
export default function Template({data}) {
const { markdownRemark } = data // data.markdownRemark holds your post data
const { frontmatter, html } = markdownRemark
return (
<div className="blog-post-container">
<div className="blog-post">
<h1>{frontmatter.title}</h1>
<h2>{frontmatter.date}</h2>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
</div>
)
}
export const pageQuery = graphql`
query($id: String!) {
markdownRemark(id: { eq: $id }) {
html
frontmatter {
date(formatString: "MMMM DD, YYYY")
slug
title
}
}
}
`
Because you haven't shared your query I've used the one in the guide but tweak it as you wish. As you can see, everything that is in the end of the frontmatter is html:
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
Using the second approach, and following the previous query structure, the html should be rendered as:
import Markdown from 'markdown-to-jsx';
import React from 'react';
<Markdown>{html}</Markdown>
If there's any hindrance I'd say that the second approach is better because, as the dangerouslySetInnerHTML name suggests, you are potentially exposing your site to XSS (Cross-Site Scripting), while the second approach sanitizes the implementation.

How can i access to 'download_url' in json using vuejs

i want to get 'tags' and 'download url' inside meta, i cannot access to 'download_url' in json how i can do it, as a backend i am using wagtail cms, and is it good to use vue js with wagtail cms (headless cms)
<template>
<div>
<div>
<b-card-group deck v-for="item in results" :key="item.id">
<b-card
>
<b-card-text>
<div v-for="block in item.body" :key="block.id">
<div v-if="block.type == 'heading'">
<h2>{{block.value}}</h2>
</div>
<div v-if="block.type == 'image'">
<img :src="'http://127.0.0.1:8000/api/v2/images/' + block.value">
</div>
<div v-if="block.type == 'paragraph'">
<h2 v-html="block.value">{{block.value}}</h2>
</div>
</div>
</b-card-text>
>
</b-card>
</b-card-group>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'Home',
data () {
return {
results: null
}
},
mounted () {
axios.get('http://127.0.0.1:8000/api/v2/pages/?type=news.NewsPage&fields=intro,body,image_thumbnail')
.then((response) => (
this.results = response.data.items
))
}
}
</script>
here is json api. i accessed till id of image and do not know what to do next
{
"id": 3,
"meta": {
"type": "wagtailimages.Image",
"detail_url": "http://localhost/api/v2/images/3/",
"tags": [
"gadget",
"phone",
"samsung"
],
"download_url": "/media/original_images/affordable_new_9-7-inch_ipad_group_fan2_1_1.png"
},
"title": "affordable_new_9-7-inch_ipad_group_fan2 1 (1).png",
"width": 528,
"height": 357
}
Assuming that response.data.items is the json you showed above, you can extract just what you want from there. Right now, your component has the whole response.data.items in this.response. So if you want all of it there, keep that.
You can store the 'tags' and 'download url' to your component by adding two new pieces of data ie add them to your data:
data () {
return {
results: null,
tags: null,
downloadUrl: null
}
... and then set those in your response block from the request's response like this.
mounted () {
axios.get('http://127.0.0.1:8000/api/v2/pages/?type=news.NewsPage&fields=intro,body,image_thumbnail')
.then((response) => (
this.results = response.data.items
this.tags = response.data.items.meta.tags
this.downloadUrl = response.data.items.download_url
))
}
When dealing with nested response objects like this, it can help to make a local variable with the data and add it that way. Also, if you dont need the whole response, you can avoid storing it and just store the data from the response that you want to your component here. If you wanted to get something from your this.response, you're going to have to go deep into it. It would be cleaner to just pull out only what you need, and then use it in your code with just one {{myStuffIPulledOut}} vs {{response.thingIWantBefore.actualThing.}}

Trouble getting data out of API using Vue JS

I'm having trouble iterating over data from a json file in Vue JS. I've got everything set up and have access to the json. What am I missing here:
JSON
{
"test": "example",
"data": [
{
"name": "My Name",
"address": "My Address"
}
]
}
Vue JS html
{{ someData['name'] }}
<ul>
<li v-for="item in someData" v-bind:key="item.id">
{{ item }}
</li>
</ul>
and my script:
created() {
this.$http.get('http://localhost:3000/properties.json').then(response => {
// get body data
this.someData = response.body
}, response => {
// error callback
});
}
The result I'm getting is:
Result
As you can see, in my v-for simply specifying item grabs each of the items here, but I want to be able to do something like {{ item['name'] }} and {{ item['address'] }}
The main problem is in your JSON file. VueJS v-for is iterating over the keys in your JSON file, in this case {{ item }} will be getting name and address. That is the reason of your output.
To solve this...
Format your JSON file as
[{name: 'John', address: 'Jane'}]
Doing this your VueJS v-for will be iterating over JSON array and {{ item }} will get the value { name: 'John', address: 'Jane' } and now you can do {{ item.name }} {{ item.address }}
An example here
EDIT: Update your API request code
created() {
this.$http.get('http://localhost:3000/properties.json').then(response => {
// get body data
this.someData = [response.body]
}, response => {
// error callback
});
}
You can simply do the following:
<template v-for="(item, key) in someData">
<span v-if="key == 'address'">{{item}}</span>
</template>
The crucial point is that the v-for="item in someData" part in the component's view iterates over values of the someData object, namely "John" and "Jane".
Depending on what exactly is your goal, you should either reformat the JSON to be an array of objects (as suggested by #F.bernal), or change the logic of v-for directive.

Typeahead 0.11.1 not adding results from JSON

I'm trying to get Typeahead to add autocompletions from my JSON source, but there are no results being added.
Some background info: I've got Sinatra serving a JSON page which takes a query param, here's the code:
get '/search' do
content_type :json
Movie.search(params[:q], {
fields: ["title^5"],
limit: 10,
load: false
}).map(&:title).to_json
end
and it's working; here's an example result.
/search?q=toy%20story returns:
["Toy Story"]
My HTML input looks like this:
<input id="search-box" type="text" value="" placeholder="Search for Movie Title" class="form-control" name="search">
and my JS:
$(function() {
$('#search-box').typeahead({
highlight: true,
limit: 10
},
{
display: 'movie',
source: function(query, syncResults, asyncResults) {
$.get('/search?q=' + encodeURIComponent(query), function(data) {
asyncResults(data);
console.log(data);
});
}
}
})
The results are showing up in the console.log as I type, and the Typeahead HTML entities are added, but with nothing in them and they're hidden.
Can anyone help? I've been stuck on this all day.
I strongly believe it is display: 'movie' that is causing your problems. If you return an array of strings, i.e ["Toy Story"] then you want to show the value of the array items :
display: 'value'
otherwise, if you work on an array of JSON items, like
[{ "title" : "2001: A Space Odyssey" } , { ... } ]
then display (or displayKey) should refer to the key / value pair you want to show in the dropdown :
display: 'title'

How to add a link <a> to the content inside of $scope.var of AngularJS

I have got my data from my controller like below.
controller:
$http.get('json/projects.json').success(function(data) {
$scope.projects = data;
});
my data in json file is something like this:
json:
{
...
projects = ['hello world', 'www.google.com', 'hello world.']
}
html:
<div ng-repeat='p in projects'> {{p}} </div>
My question is how to display 'www.google.com' as a link rather than a simple text?
You can use the liky filter from the ngSanitize module: https://docs.angularjs.org/api/ngSanitize/filter/linky
I am afraid you will have to change your 'www.google.com' to 'http://www.google.com'