Domain specific languages in django apps - Matthieu Amiguet

Tags: django, djangocon

Why would you want to have a domain specific language (DSL) in a django app? Especially for use by the actual end-users of your website?

The initial motivation was for searching contacts in a contact database. Especially the group affiliations were a problem. The rules kept changing. And what to do, for instance, with contacts that are not in groups, compared to contacts that are in a group?

Some things are very hard to do in a GUI. How would you make a GUI in which you could represent a query/action like the following?:

rotate 90
if height > 600px
    resize to height=600px
while face_dectected: f
    blur f

Something like this is easier to do in a DSL. Such a DSL might not be the thing for most users. But power users could work with it and set up add-ons for the regular users.

A DSL needs three elements:

  • A lexer uses a vocubulary to turn a bunch of characters into a bunch of words.

  • A parser uses a grammar* to turn that bunch of words into structured information.

  • The backend is supposed to do something specific with the structure information. In the example we’ll use the django ORM (specifically, Q objects).

PLY is an implementation of lex and yacc for python. Lex and yacc are the standard lexer/parser in the unix world. Because of naming conventions and introspection, ply allows you to be very economic with your code.

(Matthieu showed example code. It did indeed look economic. A bit strange in places, but very readable once he explained it. Looks fun! “A bit strange” is mostly “regex as docstring”, btw. Look at his slides)

A string like modified > 1/4/2011 OR NOT state="VA" would get turned into Q objects. state="VA" would be lexed/parsed into “field called ‘state’”, “equals operator” and “string VA”. The result is Q(state__exact='VA'), which you can feed to YourModel.objects.filter().

PLY actually works really well (and reasonably easy) when combined with Django’s query language by using those Q objects. So as long as you want to query the ORM it will be possible to use a DSL.

A more functional approach with actions is harder. You could create lambda functions and execute them. (Reinout: sounds a bit dangerous?)

(Reinout: looked like fun! And python’s dynamic character shines here, too.)

Photo & Video Sharing by SmugMug 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):