Ext.Direct remoting in Django

Well, as I didn't have a lot of other things weighing on me today, I created a Django implementation of the extdirect package I released earlier today. It's slightly more involved to set up, probably due to my not knowing Django nearly as well as Zope (suggestions welcome, Django enthusiasts), but after the initial setup writing the router classes is just as easy. Here's how to do it.

  1. Add 'extdirect.django' to INSTALLED_APPS in settings.py. This of course assumes you have extdirect installed.

  2. In views.py, define your router class and register it:

    from extdirect.django import DirectRouter, register_router
    class MyRouter(DirectRouter):
        def uppercase(self, word):
            return word.upper()
        def lowercase(self, word):
            return word.lower()
    register_router(MyRouter, 'Remote')
    The arguments to register_router are the router class, the client-side
    namespace, and an optional url under /extdirect at which the router should be
    available (defaults to the name of the class).

  3. In the __init__.py of your app, add:

    import views
    This is so that the router classes will be registered on startup; it should
    have no other effect.

  4. In the root URLconf, map the extdirect urls by adding:

    (r'^extdirect/', include('extdirect.django.urls'))

  5. In your template, load the provider definitions:

    {% load direct_providers %}
        {% direct_providers %}
    If you don't have Ext on the page already, you can write a stripped-down
    version directly to the page by adding +direct.js to the template tag:

    {% direct_providers +direct.js %}

  6. That's it. You should now have access on that template to the remote

    Remote.MyRouter.uppercase({word:'a word'}, callback); 

After that, as long as you put your router classes in views.py and register them with register_router, everything should be available in the client automatically. Neat, no?

If any Djangoers out there know how to do this more elegantly (in particular, some way to obviate the need to import views in __init__.py would be nice) please let me know. For now, though, I think it's pretty useful.


  • Brian Smith  
    November 13, 2009 at 9:30 PM

    Great work! It's almost magic :-)

    I did find a bug; if you batch together multiple requests, the server returns HTTP 500. A simple way to reproduce this is to put this in your JavaScript:

    Remote.MyRouter.uppercase({word:'a word'}, console.log);
    Remote.MyRouter.uppercase({word:'a word'}, console.log);

    The two transactions get put into an array, and something on the server side chokes. I haven't chased it down yet, but any insight would be appreciated.

Post a Comment