Django AJAX Framework

2 views
Skip to first unread message

Vladimir Pouzanov

unread,
May 25, 2006, 1:29:12 PM5/25/06
to django...@googlegroups.com
I've started this as SoC project, however is hasn't passed so I'm
publising the sources, maybe you'll find them useful.

I've uses Json as the transport layer. You will need Json-py library
(http://sourceforge.net/projects/json-py/). To make server-side code
you need to make a new django view:

from django.http import HttpResponse
from cmh.apps.rpc.minjson import write as JsonWrite
import re

def rpc(request):
if ('module' in request.GET) and ('function' in request.GET):
rx = re.compile('^[a-z]+$')
if rx.match(request.GET['module']):
try:
rpc_fn =
getattr(__import__('testproject.%s.rpc'%request.GET['module'],
'', '', ['']), request.GET['function'])
except ImportError, e:
return HttpResponse('module not found')

return HttpResponse(JsonWrite(rpc_fn(request)))
else:
return HttpResponse('bad module name')
else:
return HttpResponse('bad module')

This request accepts only module names from small latin chars, you
need to change regular expression ('^[a-z]+$') if you have other
module names. RPC functions are stored at modules' directories in
files rpc.py. You need to change 'testproject.%s.rpc' so that it point
to your module's rpc file, e.g. my CMS uses 'cmh.apps.%s.rpc' (all my
modules are stored in apps folder).

The client-side is handled by MochiKit.

<script type="text/javascript" src="/js/mochikit/MochiKit/Base.js"></script>
<script type="text/javascript" src="/js/mochikit/MochiKit/Async.js"></script>
<script type="text/javascript" src="/js/mochikit/MochiKit/DOM.js"></script>
<script type="text/javascript">

// Point to your rpc view
var baseURL = "http://localhost:8000/rpc/";

function processRPC(req)
{
json = evalJSONRequest(req);
for(var i in json) {
switch(json[i].action) {
case "replace":
var element = getElement(json[i].id);
element.innerHTML = json[i].value;
break;
// handle additional operations like
add_before, add_after, hide, show, etc.
}
}
}

function doRPC(mod, func, method, s_get, s_post)
{
var d;
var req = getXMLHttpRequest();
if (req.overrideMimeType) {
req.overrideMimeType("text/plain");
}
if(method == "GET") {
req.open("GET", baseURL + "?module=" + mod +
"&function=" + func + s_get, true);
d = sendXMLHttpRequest(req).addCallback(processRPC);
} else {
req.open("POST", baseURL + "?module=" + mod +
"&function=" + func + s_get, true);
d = sendXMLHttpRequest(req, s_post).addCallback(processRPC);
}
return d;
}
</script>

sample usage:
<a href="javascript: doRPC('rpc', 'test', 'GET', '&some_extra=args');">GET</a>

<a href="javascript: doRPC('rpc', 'test', 'POST', '',
'some_extra=args');">POST</a>

here's how you handle this call (testproject/rpc/rpc.py):
def test(args):
action1 = { 'action': 'replace', 'id': 'footer', 'value':
'<h1>footer changed ;)</h1>' }
action2 = { 'action': 'replace', 'id': 'content-related',
'value': '<h1>some more modifications</h1>' }
return [action1, action2]

Maybe this code doesn't look a django-way, but I'm still working on it.

--
Sincerely,
Vladimir "Farcaller" Pouzanov
http://www.hackndev.com

Reply all
Reply to author
Forward
0 new messages