Djangocon: Making angularjs play nice with django - Jacob Rief

Tags: djangocon, django

(One of the summaries of a talk at 2014

Remark by Jacob beforehand: there’s a bit of trend to put a lot of the UI in javascript. Fine for games and single page apps, but don’t do it for ecommerce or CMS sites that you want to have indexed by google.

Jacob Rief loves django. The three best parts according to him:

  • Single source of truth.

  • Model view control.

  • Separation of concern.

How about doing MVC on the client? A problem is that the browser UI is event-driven: you cannot do a simple one-way data binding from a model + a template to the html code.

What you need is a two-way data binding. The model and the view are contiously updated both ways. The model is the single source of thruth. Changes to the view update the model; changes to the model update the view.

This way of working is used by many javascript libraries. Angularjs is one of them.

The view itself is compiled from a template inside the html code. You mark part of the html structure with angular directives (<div ng-something="bla">) and angular then turns that into the proper view (html DOM) that’s bound in the right way to the model.

Pros of angularjs:

  • Declarative programming.

  • Doesn’t mess with the DOM manually.

  • Controllers only for the “business logic”.

  • Well suited for single page applications.

Cons of angularjs:

  • Hard learning curve.

  • Poor SEO.

He showed an example blog application. First with regular jquery javascript code. Custom-made for the form. Hardcoded IDs.

The next example used angularjs. There was much less javascript code. Most is handled by angular directives. The only javascript code was for the actual calculation (“convert string to slug”) that needed to happen: the “business logic”.

The third example improved it even more. A custom angular directive was made, which could then be added as a regular html attribute to one of the fields. Declarative!

But… now we have a new problem. How do we get all those angular attributes into our form? If we render it with {{ our_form.as_p }}, those attributes won’t be there anymore.

Solution: , there are mixin classes there to help you set it all up in the right way. See also for a full working example.

Nice! Automatic server-side form validation. With a single mixin class on your form view, you can let angularjs send the form to the server. And if it comes back with errors, they are rendered. So: no duplication of validation checks between the client and the server. See

Sometimes you don’t want to have this roundtrip and you want javascript to validate it directly. A mixin class tries to generate client side validation code for angular based on the django form field.

You can even combine both of them. The easy validation (“must be a valid email address”) happens on the client and the regular django form validation can do the more elaborate checks.

Mixing angular’s {{ something }} syntax with the same syntax as used by django’s template is of course terrible. You need to do {% verbatim %}{{ something }}{% endverbatim %}

So he always configures angularjs to look for {$ something $} instead. He hopes this could become a convention for django developers using angularjs.

A clever hack: with a mixin and a decorator, you can call methods (“remote method invocation”) on the server from within your angular code. See for some example code. Especially handy for single page apps.

A thing he’s working on: three-way data binding using websockets: the client side model is tied to the model on the server side! He demoed it: yes, if he changed something in one browser, it was propagated to the server and again propagated to a second browser. Neat!

My kids and a French steam locomotive in 2007 logo

About me

My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):