[Django]-Calling a Django view using Dajax

4👍

The deal with dajax/dajaxice is: you don’t define the dajaxice-callable ‘views’ in views.py; you create a separate ajax.py file in your app directory, and you define functions in there. These functions look and act a lot like Django view functions — for example, if you import login_required from django.contrib.auth.decorators, it’ll work on your dajax functions as it does when used on django views.

In fact, here is an ajax.py file that contains a single dajax function of mine, which searches a haystack index to populate a jQuery UI autocomplete field:

from dajax.core import Dajax
from dajaxice.core import dajaxice_functions
from haystack.query import SearchQuerySet
import ost2.portfolio.models as ax

def query(request=None, q=''):
    srcher = SearchQuerySet().models(ax.AXItem)
    dajax = Dajax()
    out = []
    valid = set()
    js_callback = "$$('#q')._callback"

    if q:
        results = srcher.autocomplete(everything=q.strip())
        bestmtch = results.best_match().uuid
        for result in results.order_by('order'):
            out.append(dict(
                value=result.title,
                label=result.object.title,
                notes=result.object.notes,
                thumburl=(result.object.keyimage and result.object.keyimage.thumbelina.url or ''),
                urlstring=result.object.urlstring,
                pk=result.object.pk,
                best=bool(bestmtch == result.uuid),
            ))

    dajax.add_data({'data': out, 'term': q}, js_callback)
    return dajax.json()

dajaxice_functions.register(query)

… in this case, I am not using dajaxice_functions.register() as a decorator — I developed this function using an earlier version of dajaxice in which you had to register your functions explicitly.

One thing you should note is: the python Dajax class instance has a number of methods that map to some action on the client (function calls, DOM manipulation, etc); in order for those methods to properly work on the client side, you set the JavaScript function Dajax.process() as the callback (sans parens in your JS code).

Another thing is: I set the default value request=None in dajaxice python function, because that makes it much easier to debug. I don’t know if you can construct stub requests in unit tests for dajaxice (I don’t think you can) but since this particular function doesn’t deal with request, it can be tested like this:

>>> from ost2.portfolio.ajax import query
>>> query(q='yo dogg')
[ ... ]

I would recommend that you try something like this after you get your ajax.py file set up, so you can test the python function independently of the JavaScript handlers and whatnot. Dajax and DajaxIce are great in many ways, but unit-test-ability is not one of them.

Good luck.

1👍

To see what is going on I propose to set up the logging facility for dajax:

Add a file handler in your settings.py under LOGGING

'handlers': {
    'mail_admins': {
        'level': 'ERROR',
        'filters': ['require_debug_false'],
        'class': 'django.utils.log.AdminEmailHandler'
    },  
    'logfile': {
        'level': 'DEBUG',
        'class': 'logging.FileHandler',
        'filename': '/path/to/your/log/django.log'
    },  

},

As second step add the dajaxice logger to the loggers

'loggers': {
   'dajaxice': {
        'handlers': ['logfile'],
        'level': 'DEBUG',
        'propagate': True,
    },
   'django.request': {
        'handlers': ['mail_admins'],
        'level': 'ERROR',
        'propagate': True,
    },
}

If you’re working on the console tail -f django.log outputs the logs live on the console …

👤loomi

Leave a comment