Login

Generic AJAX app

Author:
Rupe
Posted:
June 23, 2009
Language:
Python
Version:
1.0
Score:
-6 (after 6 ratings)

This is based on the Admin app functionality for dispatching calls.

Once you put these two files in place then add the following to urls.py:

from myProject import ajax

urlpatterns = patterns('',
    ...
    # Add this to the urlpatterns list
    (r'^ajax/(.*)', ajax.dispatcher.urls),
    ...)

you register a function or method with a name like so:

from django.contrib import ajax

def myAutoCompleteCall(request):
    ...

ajax.dispatcher.register('myAutoComplete', myAutoCompleteCall)

Then you can use the url: http://www.mysite.com/ajax/myAutoComplete

Previously I had placed this app in the django\contrib directory because I wanted to use it in an Admin app mod. Since the release of 1.1 I was able to move it out into a standard app because of the new formfield_overrides property of the ModelAdmin class.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# myProject\ajax\__init__.py
from dispatcher import dispatcher

# myProject\ajax\dispatcher.py
from django import http
import re

class AlreadyRegistered(Exception):
    pass

class NotCallable(Exception):
    pass

class Dispatcher(object):

    def __init__(self):
        self._funcs = {} # Reference name -> Ajax Function

    def register(self, name, func, force_override=False):
        if not callable(func):
            raise NotCallable('The supplied AJAX function %s is not a function (it is not callable).' % func.__name__)

        if name in self._funcs and not force_override:
            raise AlreadyRegistered('The AJAX function name %s is already registered' % name)

        # Instantiate the admin class to save in the registry
        self._funcs[name] = func

    def has_permission(self, request):
        """
        Returns True if the given HttpRequest has permission to view
        *at least one* page in the admin site.
        """
        return request.user.is_authenticated() and request.user.is_staff

    def urls(self, request, url):
        """
        Handles main URL routing for the admin app.

        `url` is the remainder of the URL -- e.g. 'comments/comment/'.
        """
        if request.method == 'GET' and not request.path.endswith('/'):
            return http.HttpResponseRedirect(request.path + '/')

        # Figure out the admin base URL path and stash it for later use
        self.root_path = re.sub(re.escape(url) + '$', '', request.path)

        url = url.rstrip('/') # Trim trailing slash, if it exists.

        # Check permission to continue or display login form.
        if not self.has_permission(request):
            return http.HttpResponseForbidden('You do not have permission to view the requested information.')

        if url == '':
            return http.HttpResponseForbidden('An AJAX function must be specified.')
        else:
            return self._funcs[url](request)

        raise http.Http404('The requested admin page does not exist.')

dispatcher = Dispatcher()

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 1 week ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 1 week ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 9 months, 4 weeks ago
  5. Help text hyperlinks by sa2812 10 months, 3 weeks ago

Comments

dougal (on June 23, 2009):

Don't add things to django.contrib or 'fake' things being in django.contrib either.

Infact, just lease django.contrib well alone! please.

#

Rupe (on July 4, 2009):

It doesn't need to go in django.contrib. I wanted to use it in some widgets I created for the Admin app and there are certain modifications where you can't avoid modifying an Admin app file. So I figured it was better to put everything in one spot.

#

Please login first before commenting.