Django ezTable provide a single view to implement server-side pagination: eztables.views.DatatablesView.
It follows the Django Class-based Views pattern and can render Array-based or Object-based JSON.
As it extends django.views.generic.list.MultipleObjectMixin it expects the model attribute to be set in both case.
Both modes expect a fields attribute that can optionnaly contains format patterns.
The exemple will use the same models as the demo:
from django.db import models
class Engine(models.Model):
name = models.CharField(max_length=128)
version = models.CharField(max_length=8, blank=True)
css_grade = models.CharField(max_length=3)
def __unicode__(self):
return '%s %s (%s)' % (self.name, self.version or '-', self.css_grade)
class Browser(models.Model):
name = models.CharField(max_length=128)
platform = models.CharField(max_length=128)
version = models.CharField(max_length=8, blank=True)
engine = models.ForeignKey(Engine)
def __unicode__(self):
return '%s %s' % (self.name, self.version or '-')
To render an array-based JSON, you must provide fields as a list or a tuple containing the field names.
from eztables.views import DatatablesView
from myapp.models import Browser
class BrowserDatatablesView(DatatablesView):
model = Browser
fields = (
'engine__name',
'name',
'platform',
'engine__version',
'engine__css_grade',
)
You can simply instanciate your datatable with:
$(function(){
$('#browser-table').dataTable({
"bPaginate": true,
"sPaginationType": "bootstrap",
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": Django.url('dt-browsers-default')
});
});
To render an array-based JSON, you must provide fields as a dict containing the mapping between the JSON fields names and the model fields.
from eztables.views import DatatablesView
from myapp.models import Browser
class ObjectBrowserDatatablesView(DatatablesView):
model = Browser
fields = {
'name': 'name',
'engine': 'engine__name',
'platform': 'platform',
'engine_version': 'engine__version',
'css_grade': 'engine__css_grade',
}
You need to use the aoColumns properties in the DataTables initialization:
$(function(){
$('#browser-table').dataTable({
"bPaginate": true,
"sPaginationType": "bootstrap",
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": Django.url('dt-browsers-objects'),
"aoColumns": [
{ "mData": "engine" },
{ "mData": "name" },
{ "mData": "platform" },
{ "mData": "engine_version" },
{ "mData": "css_grade" }
]
});
});
You can optionally provide some format patterns in the field definition:
from eztables.views import DatatablesView
from myapp.models import Browser
class FormattedBrowserDatatablesView(DatatablesView):
model = Browser
fields = (
'engine__name',
'{name} {version}',
'platform',
'engine__version',
'engine__css_grade',
)
class FormattedObjectBrowserDatatablesView(DatatablesView):
model = Browser
fields = {
'name': '{name} {version}',
'engine': 'engine__name',
'platform': 'platform',
'engine_version': 'engine__version',
'css_grade': 'engine__css_grade',
}
You can implement a custom sort method. It have to be named sort_col_X where X should be the index given by the datatables request (correspond to the filtered column).
It takes the requested direction ('' or '-') as a parameter and should return one or more Django order statement.
class CustomSortBrowserDatatablesView(BrowserDatatablesView):
def sort_col_1(self, direction):
'''Sort on version instead of name'''
return '%sversion' % direction
def sort_col_2(self, direction):
'''Sort on name and platform instead of platform'''
return ('%sname' % direction, '%splatform' % direction)
You can implement a custom search method. It has to be named search_col_X where X should be the index given by the datatables request (correspond to the filtered column).
It takes the search term and the queryset to filter as a parameter and should return the filtered queryset.
class CustomSearchBrowserDatatablesView(BrowserDatatablesView):
def search_col_1(self, search, queryset):
'''Search on version instead of name'''
return queryset.filter(version__icontains=search)