Inline editing with Jquery, Jeditable and django

…and two come along at once

In attempting to keep my current project easy to use and pleasingly contemporary, I decided to get javascripty on the user dashboard by enabling editing in place, like all the best Web 2.x sites *cough*.

Inline editing is where a user can change aspects of a page by clicking on the data to be changed, editing in a form object and sending the changed data back to the server. As I have been using Jquery for most of my UI needs, I looked for a solution that used it and found jeditable, a plugin that does exactly what I want it to do, but doesn’t seem to have been documented for django as yet, so here’s a first crack at making it work.

My user dashboard is pretty straighforward from a django perspective and uses the standard AUTH_PROFILE module. It may have to inherit some additional models shortly but in the spirit of keeping it simple, I use django.contrib.auth and a user profile model called UserProfile.

Jeditable is simple enough in a Jquery kind of way: enclose the data that you want to be edited in a div with a class identifier and specify a URL that will process the edited data in the editable function.The demo code is all PHP, but it’s simple enough to translate that to django:

$(document).ready(function() {
     $('.edit').editable('/users/dashboard/edit/{{ user.username }}/', {
     	style: 'display: inline'

My URL pattern is fairly easy to work out from that:

(r'^dashboard/edit/(?P<username>\w+)/$', 'edit_dashboard'),

In order to make it generic as possible, there should be one function for the editable area and one django view. This is the science bit. Jeditable sends a POST request which by default is formed thusly:


This isn’t explained that well on the Jeditable page in my opinion, but the author is Finnish so we’ll let him off. What it means is that the name of the div class is sent a value pair with ‘id’ and the edited data is sent as ‘value’. This is modifiable but it’s as good a default as any to use.

In keeping with django’s MVC structure, set the div element name (‘id’) to be the same as the associated model field. There’s probably a more dynamic way of doing this, such as defining the div element as the field name from the dictionary created by the view, but creating it by hand will be fine. Each div element therefore looks something like this:

<div class="edit" id="first_name">{{ user_obj.user.first_name }}</div>

Pass the field and its value to the view using request.POST.get():

            field = request.POST.get('id', '')
            value = request.POST.get('value', '')

This is where I got a bit stuck for a while. I have the field and I have the value, how do I pass them to the object to be saved? The answer was found in this post by James Bennett. A model, or object derived from a model has an API that calls all sorts of useful information about your model, and, more to the point can be invoked to modify that information in a generic way. The _meta functions are part of django’s internals, and as a comment in the post points out, might be subject to change, but we don’t need to the _meta functions, as the API call that we’re interested in, __setattr__ is also exposed directly to the model or object, so the field and value can be passed to the database like this:

user_obj.__setattr__(field, value)

and can be saved with a simple save() method. Try it in a shell.

UPDATE: this doesn’t work with the User.first_name and User.last_name fields. They can be accessed using

user_obj.user.__setattr__(field, value)

and saved with The first_name and last_name field in auth seem to be largely deprecated and so might be better off in UserProfile: it certainly saves a couple of lines of code.

Jeditable expects a response, which a PHP author would roll themselves. Fortunately, django has HttpResponse. I return the value variable, which is displayed as the edited data. The stored data will not be shown until the page is fully reloaded.

This example is pretty primitive really, and there are things that seem to be able to be improved. The database query is a simple user.get_profile() call but this request gets made for every item that is changed, which seems inefficient. It seems there should be something a bit more asynchronous about it , possibly using JSON or XML and making a periodic save rather than a query for every item. A bit of processing power could be saved if we checked if the data had changed before saving it. However, at the moment I’m a programmer with a deadline 😉


One response to “Inline editing with Jquery, Jeditable and django

  1. Hey dude, you might be interested in toggleEdit ( It’s like jeditable but i think it’s a better fit for django because it gives you total control over the forming of the post request e.g. you go form.serialize() on the parent form then in the django view you can just parse it like a normal form. Also you call it on inputs which is good because django has ModelForms and it’s easy to generate inputs.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s