Passing data from Django views to vue instance as JSON object - html

I have the following Django view method, being used to send information over to some Vue.js frontend code in details.html. I am basically wondering how do I send over the data to the vue template. How do I do JSON dumps? I think that is what I am messing up here.
def works(request):
heading_info = Heading.objects.order_by('-name')[:1]
welcome_info = Welcome.objects.order_by('-title')[:1]
skills_info = Skill.objects.order_by('position')[:5]
projects_info = Project.objects.order_by('name')[:10]
items = []
items.append({'heading_info':heading_info, 'welcome_info':welcome_info, 'path':path, 'path2':path2, 'skills_info':skills_info,'projects_info':projects_info})
# context = {}
# context["items_json"] = json.dumps(items)
context = {'heading_info':heading_info, 'welcome_info':welcome_info, 'path':path, 'path2':path2, 'skills_info':skills_info,'projects_info':projects_info}
return render(request, 'home/details.html', context)
And here is my html where I am trying to access this data.
<script type='text/javascript'>
var data = {{ projects_info|safe }};
</script>
<div id="app">
[[projects_info_vue]]
{% comment %} #Passing array as vue data. This gets rendered as QuerySet. How do I access these value in Vue. {% endcomment %}
<div class="row">
{% for project in projects_info %}
{% comment %} #Here is the array being rednered in Django. This array gets rendered as a QuerySet in Vue. {% endcomment %}
<div class="col">
{{project.name}}
</div>
{% endfor %}
</div>
</div>
<script>
var app = new Vue({
delimiters: ["[[", "]]"],
el: '#app',
data: {
projects_info_vue: '{{projects_info}}',
},
});
</script>

You're absolutely correct that at some point you will need to convert your Python object into a literal that is understandable by Javascript/Vue, and yes JSON is appropriate since your data is more complex than a single value (string, number, etc).
To convert your QuerySet into a json string, a good approach is to first convert it from a QuerySet object into a list of simple dictionaries using values() and then encode this into json. Example:
import json
j = json.dumps(list(Project.objects.order_by('name')[:10].values('name','id')))
You will need to adjust the parameters to values to include the fields you are interested in, or omit them entirely to include all fields.
Alternatively, you can use a seralizer to directly encode the QuerySet.
I believe the rest of your code should work without much tweaking once you've gotten the JSON on the template output. You can render the json directly into the component data as you are doing or alternatively as a component property.
I will note however that the typical approach to retrieving "complex" data from Django in a JSON format is via Django Rest Framework. Using your approach for simple properties is quite fine, but when you start pulling larger datasets, you'll realize some performance gains by having your Vue components make async requests to fetch the data. This comes at the cost of additional complexity, though (managing ajax requests/responses and state in your Vue code).
PS. I know it's not your question, but I wanted to point out that I believe there are shortcomings to the general approach of using Vue via script tags on your Django template, most notably missing out on the ease and convenience of Single File Components (SFCs), hot-reloading, and the optimizations of webpack. Unless your project is tiny, I recommend spending a bit of time setting up such an integration; in my experience the up-front effort is well worth it. Also, the setup isn't so tough, as I've written some articles describing the approach and built a cookiecutter to boostrap Vue+Django projects.
Good hacking!

Related

jinja template: use an jinja template into an another jinja template for his naming

I'm writing a dag model and my goal is to make it as generic as possible. For this, I use the jinja models coupled with the airflow connection to store the customer credentials. it works fine.
In order to go further, during my tasks, I want to be able to retrieve data in an airflow connection with the jinja models which I will then use to format another jinja model that I then need to retrieve.
For instance:
--context_param MYSQL_MONITORING_FLOW_HOST={{ conn.{{ conn.NEWCLIENTTEST_DATASOURCE.extra_dejson.MYSQL_BDD_SERVER_ID }}.host }}
{{ conn.NEWCLIENTTEST_DATASOURCE.extra_dejson.MYSQL_BDD_SERVER_ID }} tested alone returns the correct value (MYSQL_GENERIC_ID) and then {{ conn.MYSQL_GENERIC_ID.host }} also returns the correct value.
I would like it to do a double interpretation of the jinja template, is that possible?
Thank you very much for your help
cdt
Matthew

Accessing a decoded json string value in twig

I am working on a Symfony project and need to loop through data to populate saved fields in a form (specifically the number of bed types in a property). I save the data in the database table as a json string, as follows:
{"2":"5","3":"0","4":"0","5":"0","6":"0","7":"0"}
This JSON follows the structure "BEDID": NUMBER OF BEDS. I implemented the solution regarding decoding json in twig as stated here https://stackoverflow.com/a/14504988/5194337 but I am having trouble actually being able to access each specific value in the decoded json. I use this in the twig template to decode the json (based on the fact my data is stored in a variable called specifics and website.id references one of multiple websites owned by the user:
{% set beds = specifics[website.id].0.standardBedTypes|json_decode %}
So, once I do this, I try and access the value of each number of beds as follows:
{{ beds[standard_bed.id] }}
standard_bed being the value in the for loop. But, when I load the page I get the following error:
Impossible to access a key "2" on an object of class "stdClass" that
does not implement ArrayAccess interface.
I guess this means that the decoded value of the json is technically not an array, but I cannot think of any other method of referencing each value, so help with this is appreciated.
From the documentation here, you can pass it as an option. See the options here.
You want to pass JSON_OBJECT_AS_ARRAY
Decodes JSON objects as PHP array.
So basically you want to do:
{% set beds = specifics[website.id].0.standardBedTypes|json_decode(constant('JSON_OBJECT_AS_ARRAY')) %}
If you want to access to objects properties, you can do it using the attribute function.

How can I create a json object using Angular and display it using html?

Basically I am working with a json object that I know nothing about, I don't know its keys, I don't know its value. I managed get work with it and process all the information that I want, at the end I have an array (I need an array to be able to do what I want) with all the keys and their paths in the json. Is there a way I can put it back in a json and display it using html ?
If you don't want to use a devTool to display your json Object you can do this in your template :
<div>{{ yourObject | json}}</div>
Step 1:
Simple Javascript: const arrayAsJson = JSON.stringify(yourArray)
Step 2: To display the data follow the answer from #Bougarfaoui El houcine and as mentioned in the comments to get a formated output:
<pre>{{ arrayAsJson | json }}</pre>

Convert a String to JSON in scala.html file

I am currently using a list of PropertyDTO s in my scala.html file to populate a view with Play2. The propertyDTO has a String attribute "value" which contains a JSON String. I want to convert this string to a JSON object in the scala.html file, and iterate through the JSON object collection. When trying the following,
val json = Json.parse(property.value),as[JsObject] within the scala code, it prints the expression. I would wish to know if my approach is correct, and if not , is there a suitable solution.
Code --> scala.html
#(propertyList : List[PropertyDTO])
#for(property <- propertyList){
#if(property.isInputProperty){
#if(property.propertyType=="BL"){
val json = Json.parse(property.value).as[JsObject]
}
}
}
I would not advise doing this in a template - the point of having templates, and not embedding HTML generation directly into your Scala code, is to separate the view logic from the application logic. If you go embedding Scala code like this in your template, then what's the point in using a template?
Best practice is to prepare all your data for rendering before calling the template, and then pass it into the template, and keep the template as dumb as possible, just iterating and rendering values.
The problem is that you need to declare code to be interpreted as scala code by putting an # in front of it. The line
val json = Json.parse(property.value).as[JsObject]
gets interpreted as HTML as there is no # sign in the line indicating scala code. What you can do is declare a whole block to contain scala code using #{ ... }.
For example you can store the result of your for comprehension in a variable for later use in the template:
#import play.api.libs.json._
#validPropertiesAsJson = #{
for{
property <- propertyList
if property.isInputProperty
if property.propertyType == "BL"
} yield Json.parse(property.value).as[JsObject]
}
And later in the template use #validPropertiesAsJson to include the value.
More information can be found in the playframework documentation: http://www.playframework.com/documentation/2.2.0/ScalaTemplates
Keep in mind to put as little logic into the template as possible.

Twig & Smarty: object from JSON file

I'm learning both Twig and Smarty and I didn't find an answer for my question for both of them. The question is: is there some built-in way to read variable's value from separate JSON file? I'll use Twig for my examples. OK, this is regular Twig variable definition:
{% set vars = {"foo" : "bar"} %}
Now let's assume that we have a JSON file at /var/www/html/website.com/vars.json that contains:
{
"foo" : "bar"
}
And now I want to initialize my vars with this object, but read it from file instead of definition in the template, something like that:
{% set vars = *some_magic* "/var/www/html/website.com/vars.json" %}
Or, the better example, to use object from the file as include parameter:
{% include "menu.html" with *some_magic* "/var/www/html/website.com/menu.json" only %}
So, is there some build-in way, or, at least, what is the best way to implement it as an extenstion?
You can write your own custom twig function e.g. loadFromJsonFile(filename) and use it like {% set data = loadFromJsonFile('/var/www/html/website.com/menu.json') %}
Here is
how to extend twig in symfony 2
twig documentation