3

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>
Remo Bajwa
  • 513
  • 6
  • 19

1 Answers1

3

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!

ilikerobots
  • 787
  • 6
  • 16
  • 1
    Awesome article! I think I will try incorporating Vue using the method you described. – Remo Bajwa Oct 07 '20 at 02:25
  • 1
    I was also wondering how much more tricky is it to run it on Heroku? Have you tried deploying it on a server yet? – Remo Bajwa Oct 07 '20 at 02:31
  • 1
    @RemoBajwa I have a production deployment using docker-compose, fairly close to the docker setup advised by the pydanny django cookiecutter. I have not tried with Heroku. However, I don't think there's much additional effort beyond a standard django deployment: just a yarn/npm build before collecting static. – ilikerobots Oct 07 '20 at 08:26