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 optionnaly 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 take the requested direction ('' or '-') as 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 have 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 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)