Concept

server browser relations

The idea is to create an interface between server and client side classes that know how to communicate with each other. This is done by creating a JS file with the same name as the URL name that is mapped to the corresponding Django view class. That file is loaded by RequireJS and executed automatically for all requests.

Client Side

Since javascript doesn’t support class definitions and inheritance I recommend using coffeescript or typescript to simply inherit from the base View() class. You can still use javascript though by using the built in extendjs function to mimic class inheritance.

my_view.js
 define(['ajaxviews'], function(ajaxviews) {
   var MyView = ajaxviews.extendjs(ajaxviews.View);
   MyView.prototype.onLoad = function () {
     // access class instance variables and methods with 'this'
   };
   return MyView;
 });
my_view.coffee
 define ['ajaxviews'], (ajaxviews) ->
   class MyView extends ajaxviews.View
     onLoad: ->
       # access class instance with '@'
my_view.ts
 define(['ajaxviews'], function(ajaxviews) {
   class MyView extends ajaxviews.View {
     onLoad() {
       // access class instance with 'this'
     }
   }
 }

For this to work you need to set up RequireJS and place the JS files inside the views directory which is located in JS root. In main.js require the ajaxviews module and initialize the App. This will execute the View class whose file name equals the URL name from Django’s URL conf.

main.js
 // setup require config

 require(['ajaxviews'], function(ajaxviews) {
   var App = ajaxviews.App;

   App.config({
     // options
   });

   App.init();
 });

Server Side

The server side ajaxviews app provides view and form classes you can inherit from.

urls.py
 from django.conf.urls import url
 from .views import MyAjaxView

 urlpatterns = [
     url(r'^my/view/$', MyAjaxView.as_view(),
         name='my_view'),
 ]
views.py
 from django.views.generic import View
 from ajaxviews.views import GenericBaseView

 class MyAjaxView(GenericBaseView, View):
     ajax_view = True

The ajaxviews.views.GenericBaseView takes care of passing the URL name the view class is mapped to, to the client side App. Add ajax_view = True to the class if you have created a corresponding JS file. If not you can omit the ajax_view property or set it to False.

base.html
<script id="config" type="application/json">{{ json_cfg }}</script>

The JSON config script is the communication channel for sites requested via URL. It’s included in the base html template by the AjaxMiddleware along with the require main script.

base.html
 {% load require %}
 {% require_module 'main' %}

RequireJS loads the main.js file located in JS root. The module loading is handled by django-require‘s templatetag require_module.

{% extends generic_template|default:'base.html' %}
Template inheritance

Extend templates from generic_template to be able to update the view via AJAX by calling View.requestView(). Set the default tag to the base template that’s used for requests via URL. The #ajax-content is the scope that’s replaced when the view is updated.