Welcome to Django ezTables’s documentation!¶
Django ezTables provides easy integration between jQuery DataTables and Django.
Compatibility¶
Django ezTables requires Python 2.6+, Django 1.4+ and Django.js 0.7.6+.
Installation¶
You can install Django ezTables with pip:
$ pip install django-eztables
or with easy_install:
$ easy_install django-eztables
Add djangojs
and eztables
to your settings.INSTALLED_APPS
.
If you want to run the test suite, you will need some additionnal dependencies. You can install them in the same time with:
$ pip install django-eztables[tests]
Features¶
Datatables.net, plugins and localization integration with Django.
- Server-side processing with a simple view supporting:
- sorting (single and multi columns)
- filtering with regex support (global and by column)
- formatting using format pattern
Deferred loading support.
Twitter Bootstrap integration.
Demo¶
You can try the demo by cloning this repository and running the test server with the provided data:
$ python manage.py syncdb
$ python manage.py loaddata eztables/demo/fixtures/browsers.json
$ python manage.py runserver
Then open your browser to http://localhost:8000
Documentation¶
Template tags¶
Initialization¶
You can either:
- load the template tag lib into each template manually:
{% load eztables %}
- load the template tag lib by adding it to your
views.py
:
from django.template import add_to_builtins
add_to_builtins('eztables.templatetags.eztables')
Usage¶
datatables_js¶
A {% datatables_js %}
tag is available to include the datatables javascript library.
After loading, you can use the Datatables library as usual:
<table id="my-table">
</table>
{% datatables_js %}
<script>
$('#my-table').dataTable();
</script>
bootstrap support¶
If you want to use the twitter bootstrap style (based on this blog post), 2 template tags are provided for:
{% datatables_bootstrap_js %}
for the javascript part.{% datatables_bootstrap_css %}
for the css part.
<head>
{% datatables_bootstrap_css %}
{% datatables_js %}
{% datatables_bootstrap_js %}
</head>
<table id="my-table">
</table>
<script>
$('#my-table').dataTable({
"bPaginate": true,
"sPaginationType": "bootstrap",
"bScrollCollapse": true
});
</script>
Server-side processing¶
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 '-')
Array-based JSON¶
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')
});
});
Object-based JSON¶
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" }
]
});
});
Format patterns¶
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',
}
Custom sort¶
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)
Custom search¶
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)
SQLite Warnings¶
Be carefull some field types are not compatible with regex search on SQLite and will be ignored (filtering will no performed on this fields).
Ignored fields type are:
- BigIntegerField
- BooleanField
- DecimalField
- FloatField
- IntegerField
- NullBooleanField
- PositiveIntegerField
- PositiveSmallIntegerField
- SmallIntegerField
Localization¶
Django ezTable embed DataTables localizations.
They have the following naming convention:
{{STATIC_URL}}/js/libs/datatables/language.{{LANG}}.json
You can simply retrieve them with django.js:
$('#my-table').dataTable({
...
"oLanguage": {
"sUrl": Django.file("js/libs/datatables/language.fr.json")
}
...
});
You can obtain the current language code with django.js too:
var code = Django.context.LANGUAGE_CODE;
Be careful, no localization is provided for the English language.
Integration with other tools¶
Django Pipeline¶
If you want to compress Django ezTables with Django Pipeline, you should change the way you load it.
First add jQuery, Django.js and jQuery Datatables (and optionnaly bootstrap support) to your pipelines in your settings.py
:
PIPELINE_JS = {
'base': {
'source_filenames': (
'...',
'js/libs/jquery-2.0.0.js',
'js/djangojs/django.js',
'js/libs/datatables/jquery.dataTables.js',
'js/libs/datatables/datatables.bootstrap.js',
'...',
),
'output_filename': 'js/base.min.js',
},
}
Add Datatables Bootstrap CSS to your CSS pipeline:
PIPELINE_CSS = {
'base': {
'source_filenames': (
'...',
'css/datatables.bootstrap.css',
'...',
),
'output_filename': 'js/base.min.css',
},
}
Instead of using the django_js
template tag:
{% load js %}
{% django_js %}
you should use the django_js_init
and include your compressed bundle:
{% load js compressed %}
{% django_js_init %}
{% compressed_js "base" %}
RequireJS¶
Django ezTables works with RequireJS but it requires some extras step to do it.
Preloading prerequisites¶
You should use the django_js_init
template tag before loading your application with RequireJS.
{% load js %}
{% django_js_init %}
<script data-main="scripts/main" src="scripts/require.js"></script>
It works with django-require too:
{% load js require %}
{% django_js_init %}
{% require_module 'main' %}
path and shim configuration¶
You should add extras paths and shim configurations for Django.js and Datatables:
require.config({
paths: {
'jquery': 'libs/jquery-2.0.0',
'django': 'djangojs/django',
'datatables': 'libs/datatables/js/jquery.dataTables.min',
'datatables.bootstrap': 'libs/datatables/js/datatables.bootstrap'
},
shim: {
'bootstrap': {
deps: ['jquery'],
exports: '$.fn.popover'
},
'django': {
"deps": ["jquery"],
"exports": "Django"
},
'datatables': {
deps: ["jquery"],
"exports": "$.fn.dataTable"
},
'datatables.bootstrap': {
deps: ["datatables"]
}
}
});
Paths are relative to {{STATIC_URL}}/js
. Adapt it to your configuration.
API¶
eztables.forms
– DataTables pagination form processing¶
-
class
eztables.forms.
DatatablesForm
(*args, **kwargs)[source]¶ Bases:
django.forms.forms.Form
Datatables server side processing Form
See: http://www.datatables.net/usage/server-side
-
bRegex
= None¶ True if the global filter should be treated as a regular expression for advanced filtering, false if not.
-
iColumns
= None¶ Number of columns being displayed (useful for getting individual column search info)
-
iDisplayLength
= None¶ Number of records that the table can display in the current draw. It is expected that the number of records returned will be equal to this number, unless the server has fewer records to return.
-
iDisplayStart
= None¶ Display start point in the current data set.
-
iSortingCols
= None¶ Number of columns to sort on
-
sEcho
= None¶ Information for DataTables to use for rendering.
-
sSearch
= None¶ Global search field
-
eztables.views
– DataTables server-side processing view¶
-
class
eztables.views.
DatatablesView
(**kwargs)[source]¶ Bases:
django.views.generic.list.MultipleObjectMixin
,django.views.generic.base.View
Render a paginated server-side Datatables JSON view.
-
eztables.views.
UNSUPPORTED_REGEX_FIELDS
= (<class 'django.db.models.fields.IntegerField'>, <class 'django.db.models.fields.BooleanField'>, <class 'django.db.models.fields.NullBooleanField'>, <class 'django.db.models.fields.FloatField'>, <class 'django.db.models.fields.DecimalField'>)¶ SQLite unsupported field types for regex lookups
eztables.templatetags.eztables
– Template tags¶
Contributing¶
Django ezTables is open-source and very open to contributions.
Submitting issues¶
Issues are contributions in a way so don’t hesitate to submit reports on the official bugtracker.
Provide as much informations as possible to specify the issues:
- the Django.js and Django ezTables versions used
- a stacktrace
- installed applications list
- ...
Submitting patches (bugfix, features, ...)¶
If you want to contribute some code:
- fork the official Django ezTables repository
- create a branch with an explicit name (like
my-new-feature
orissue-XX
) - do your work in it
- rebase it on the master branch from the official repository (cleanup your history by performing an interactive rebase)
- submit your pull-request
There are some rules to follow:
- your contribution should be documented (if needed)
- your contribution should be tested and the test suite should pass successfully
- your code should be mostly PEP8 compatible with a 120 characters line length
- your contribution should support both Python 2 and 3 (use
tox
to test)
You need to install some dependencies to hack on Django ezTables:
$ pip install -r requirements/develop.pip
A Makefile is provided to simplify the common tasks:
$ make
Makefile for Django ezTables
Usage:
make serve Run the test server
make test Run the test suite
make coverage Run a caoverage report from the test suite
make pep8 Run the PEP8 report
make pylint Run the pylint report
make doc Generate the documentation
make minify Minify all JS files with yuglify
make dist Generate a distributable package
make minify Minify Django.js with yuglify
make clean Remove all temporary and generated artifacts
To ensure everything is fine before submission, use tox
.
It will run the test suite on all the supported Python version
and ensure the documentation is generating.
$ pip install tox
$ tox
You also need to ensure your code is PEP8 compliant (following the project rules: see pep8.rc
file):
$ make pep8
Don’t forget client-side code and tests.
You can run the javascript test suite in the browser (http://localhost:8000). Javascript tests are run in the test suite too, but it runs on the minified version of the javascript libary.
You can use the Makefile minify
task that minify the javascript:
$ make minify test
Note
minification use yuglify
so you need to install it before: npm install -g yuglify
Changelog¶
Current¶
- nothing yet
0.3.2 (2013-06-07)¶
- Python 2.6 support
0.3.0 (2013-04-30)¶
- Python 3 support
- Documented integration with Django Pipeline or RequireJS
- Package the unminified version too (used when
settings.DEBUG=True
)
0.2.2 (2013-03-02)¶
- Django 1.5 compatibility
- Added custom search and sort demo
0.2.1 (2013-02-08)¶
- Fix formatting with unicode
0.2 (2013-02-07)¶
- Handle custom server-side search implementation
- Handle custom server-side sort implementation
0.1.2 (2013-02-07)¶
- Fix static files packaging
0.1.1 (2013-02-07)¶
- Fix requirements packaging
0.1 (2013-02-07)¶
- Initial implementation