7

I've found a few posts about this. But I'm still confused.
I want to use django rest framework api to be consumed by vue. My questions:

  1. Should I use django templates at all? I guess not, cause the django templates syntax clashes with vue. But still I need to serve templates - should I just use static templates with apache?

  2. Assuming I do use static templates, how can I prerender pages like with django templates?
    I mean, with django I have a url like /resource?id=5,
    But with rest api, it will be vue responsibility to fetch the id=5 resource from the url and to do the rendering, But I don't like the need for extra xhr.

  3. It seems that all the docs assume I use node.js, I don't. Do I have to use another node.js server in addition to the django apache server?

  4. Does vue.js with webpack/npm force a specific app folder structure? How that works with the normal django project structure?

1
  • 1
    My 2 cents: 1: serve not static templates, but static html/js files with apache. 2: use vue-router (with history-mode); 3: no, you don't need a node.js server. 4: there are some recommendations, but they don't really force a structure. As long as every file finds the dependencies it needs, it will be fine. Commented Mar 25, 2018 at 20:24

2 Answers 2

15

The first thing to know about vue is that it scales really well. You can do entire single page applications with it and let vue drive your entire frontend or you can use it to just build single components with more interactivity and have the rest rendered with something else. The answer to your question depends on what you go for. Typically an SPA (Single Page Application) feels more modern and from my experience, produces a cleaner seperation of concerns, so personally I'd go with that, but I'll describe both strategies:

Building an SPA:

  1. No, in this case not. When building an SPA your back- and frontend are completely decoupled. You'll render everything with vue and use the vue router for routing. Django shouldn't need to know about your frontend, it should just expose an API (REST for example). In this case your frontend becomes one implementation of that API, using asynchronous data fetching, for example with axios, to get the necessary models from your Django Backend. Also, there is no need for django to serve your templates, just build the vue project and put the files on a server.

  2. The vue router has a nice encapsulation for these things, you don't have to get the params from the url yourself, it'll handle that for you and pass those params directly to your component, see here. And yes, there will be a need for extra XHR, but consider the following scenario: When using django to render pages, django will output a way bigger html file than vue to begin with. So the "extra loading" that vue needs is just shifted a bit, but there's not a huge increase in traffic.

  3. Vue is purely a frontend framework so it doesn't care what backend you're using. Because it's only frontend the output of webpack will be raw html, js and css. There is no need for a node server, anything that can deliver those files will do the job. However, becuase vue renders completly in the browser it's really hard for search engines to crawl your SPA. To work around that there's something called server-side rendering. If you feel that you need SEO you might want to check out Nuxt.js. When going for the server-side rendering approach you will need a node server, otherwhise not.

  4. In the SPA scenario you don't care. In fact, the SPA can be on a completly different server and still function properly with your django backend, as it uses purely asynchronous calls to get all the data.

Using Vue just for single components:

  1. In this case you want to use django to render most of your sites data. Only if you need interactivity or asynchronous calls you should write vue components. You can put those directly into your django templates, just keep in mind that the rendering of the components will be done completly in the users browser.

  2. Even in this case the impact is little. Build your vue project with webpack, put the compiled js/css files in the assets folder of django (I'm not a django expert but it simply needs to be accessible for django). Then just make sure you're including all of them (have a look at the index.html header that vue build command produdces) in the header of your django template and make sure that the parent tag of your application has the correct id for vue to bootstrap the application, for example the default is: <div id="app">...</div> That's all.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, I am building an SPA. I dont like that my page will have to use extra xhr to fetch data. That will make the page SEO unfriendly. I would like to prerender html, but I dont want to setup a node server
And isn't a node server required at least for development? when using hot reloading of ES6 JS and so on
Like I mentioned you can use Nuxt to server side render your views. Nuxt allows you to pre-fetch data from an api before delivering the page to a client. But you will need an extra node server for that, you can still run django normally though, it doesn't exclude each other. Also don't worry about the setup, node is super easy to setup, just follow the Nuxt guide. Also you need a node server for development, but when you use vue-cli it comes with that so you don't have to worry about anything, as it's just local anyway. It's fairly similar to how django's local dev server works.
4

Having just implemented a Vue+Django project myself, I can vouch for everything Philip Feldmann said in his detailed response.

I'll emphasize a point though that seems like it's little hazy from the question you're asking. From an architectural viewpoint, Vue and Vue's router are handling what you would traditionally associate with URL navigation and changes in the user's visual experience of your site/app.

On the Django side, you're essentially doing away with rendering all of the HTML. Rather, what you're mapping requests to via urls.py and traditional Django routing is Python code to generate and return the data consumed by your Vue application. So your requests that are mapped into your Django app return things like JSON, not fully formed web pages.

That's why you don't need conventional Django templates in the traditional sense. Instead, your Django methods that handle requests will do things like validating the request sent by your view parameters (usually a http POST request), making sure things like authentication and authorization are handled correctly, and then doing database model queries to get data to return via JSON or whatever serialization you're expecting on the client side, and Django becomes basically a back-end only solution.

Having been playing with this for quite a while, I'll tell you that using Django this way has been especially nice... The Django admin makes for a great place to work with the backend of the Vue app. I know a lot of people are hot for the Vue+Node setup, but if you're a Python guy and know a little about Django, this is a great alternative.

2 Comments

When you render a page, so you need extra xhr to fetch data associated with the template? And if you have a few urls for different models, and you want to fetch all of them in a single request?
Typically, yes. You could in theory bundle up your data so that it came down in the initial request if you knew enough about what the app needed with the initial load, however that'd be atypical. Think about what your app is likely doing if it's a SPA. On the first request, it's going to bring down the basic HTML and all the JavaScript bundles that implement your app. At that point, there's a lot of user interaction, including potentially logging in or routing to another page. Each of these will require some sort of round-trip to the server for data. You'll probably make lots of data requests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.