Creating SPAs with Django can be complicated or simple depending on how clearly you understand how it works. There are many different options, js build tools and strategies for creating SPAs with Django that can quickly cloud your understanding. I have some thoughts that might make things easier to understand.

What is going on?!?

Learning new things can be confusing at first, and putting a SPA into Django is no exception. Many tutorials go deep into build tool specifics, and if you aren't sure yet how SPAs fit into Django, confusion can snowball quickly. Whether it be Ember, React, Angular1/2, or whatever new framework/library people are using, implementation is never straightforward the first go-around.

For me, the most confusing part was always figuring out how build tools work, and separating server setup from client setup. Tutorials often have a lot of both server and client tasks and I was never sure what was doing what, or how things worked. There's one piece of information that would have made things easier for me from the beginning.

The job of a javascript build tool is to create three files. An html file, a js file, and a css file.

It doesn't matter if it's using a CLI tool, using ES6, Typescript, Grunt, Gulp, Webpack, etc etc etc. Everyone has their preference of how to build a js application, but the end output that django will use will always be html, js, and css. The html file will need to be rendered by django, and the js/css file(s) will need to be served by django staticfiles.

It's important to differentiate what's specific to the js application, and what's specific to how Django is hosting the SPA.

Hook up a pseudo SPA

We will not be focusing on the js framework yet, but rather first just getting Django to recognize index.html, style.css and app.js. Adding in the actual SPA we will do a little bit later, for now we're only going to be focusing on what Django is responsible for.

Ok, let's get all the pieces into place. We will create an index.html, app.js and style.css and make sure we have everything hooked up. We will switch them out later, but I just want to make sure it's clear that we are using 3 files which make the full SPA.

First thing is to setup a blank project. If you need help with setting up a blank project, you can check out my video on installataion and environment setup.

I'm going to get my blank url to display a template called index.html. To do that, all we need to do is tell django where to look for templates and create the template. By default, it just looks in app folders, but we don't have a need for any apps yet, so I'm going to place a `templates` folder at my root directory and let Django know to look there. After that, in the urls.py I'm going to setup a simple TemplateView.


# settings.py
TEMPLATES = [
    {
       ...
        'DIRS': ['templates'],
       ...
    }
]

# urls.py
from django.conf.urls import url
from django.contrib import admin

from django.views.generic.base import TemplateView

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', TemplateView.as_view(template_name="index.html")),
]

At this point you should be able to runserver and see your index.html file, whatever you choose to put there.

The next step is to hookup a blank css and js static file and to make sure those are loaded correctly. I'm going to make a folder called 'static' in my root directory, make 2 subfolders called 'js' and 'css', and then put the files in their respective folders. All pretty standard stuff so far, right?


index.html
< head>
    ...
    < link rel="stylesheet" href="/static/css/style.css" media="screen">
    < script src="/static/js/app.js">
< /head>

static
--css
----style.css
--js
----app.js

Verify that the css and js files are being loaded. Look in the chrome dev tools network tab and/or make an obvious css change such as setting the body background grey.

Ok so at this point, we have done nothing cool and this should all seem very standard. I'm sorry. However, this is the ENTIRE part that django is responsible for in a SPA. So what we did was kind of cool, you just didn't know it yet. Before moving onto creating the actual SPA, it's important to understand what Django is responsible for.

Ok so... the SPA?

From this point, the options are endless. You can use any build tool you'd like, with any framework/library you choose. The end product of what you produce will be a mixture of js, css, and html. Django will need to be aware of these files.

Instead of making another "How to make a SPA" tutorial, I'm going to leave you with one particular article from scotch.io I found recently I really like. It shows how to setup a React SPA, and what I like about it is that they explain what's going on. Go through that article and hook up the application to your Django server. In the last section of this article, you'll find some sample code of me implementing their React App within Django. If you get stuck take a look at that code and see if you can solve your problem.

Some pointers
  1. You will need to tell django where static files are. Your build tool will create js & css files, and you'll need to modify your STATICFILES_DIRS setting to tell django where to find the generated files.

  2. You will need to tell django where to find the index.html file. In your urls.py or views.py you'll specify somewhere to look for index.html (or whatever you name it). You can change your TEMPLATES DIRS setting to look in the directory that your build tool puts it into, or you can change your build tool to put the index.html file in a more convenient place.

  3. You're going to have your build tool generating files in your django project directory. I typically create a folder called `app` and have the build tool place code there, but you should have your js build files (package.json, webpack.config.js, .babelrc, etc) at the top level of your project.

Have some more tips that helped you? Have any ground-breaking revelations to share? Please don't hesitate to share them with other readers in the comments!

My django-spa template

I've created a django-spa repository that you can fork for a quickstart on creating your own Django SPA project. The master branch contains what I consider to be a blank slate where you can add any SPA you choose. I also have a fork for react, which goes through the react-router article by scotch.io I linked above. The goal is to make more forks for other SPAs, but at the time of writing this article I have only added react.

If this is your first time setting up a SPA in Django, I strongly urge you not to fork this, but just use the code as a reference if you get stuck. After you get the hang of things and understand what's going on, you can just clone and go very quickly. It's a beautiful world. Happy Djangoing!!!