A script for using the jQuery plug-in DataTables server-side processing (and DataTables Editor) with MongoDB.
Works with Flask and Django. Supports column sorting and filtering by multiple search terms and/or column specific searches like column:keyword.
- https://github.com/pauljolsen/django-and-mongo-datatables
- https://github.com/pauljolsen/flask-and-mongo-datatables
You can install with pip:
pip install mongo-datatables
In your views.py
:
import json from flask import request, render_template from mongo_datatables import DataTables from app import mongo from . import main @main.route('/table-view') def table_view(): return render_template('main/table_view.html') @main.route('/mongo/<collection>') def api_db(collection): request_args = json.loads(request.values.get("args")) results = DataTables(mongo, collection, request_args).get_rows() return json.dumps(results)
In your table_view.html
:
{% extends "base.html" %} {% block content %} {{ super() }} <div class="container"> <h1> Contracts </h1> <table id="dt_table" class="table table-striped table-responsive"> <thead> <tr> <th>ExpiryDate</th> <th>ContractId</th> <th>Vendor</th> <th>Note</th> </tr> </thead> </table> </div> {% endblock %} {% block scripts %} {{ super() }} // DataTables, jQuery, Bootstrap loaded here <script> $(function () { $('#dt_table').DataTable({ serverSide: true, ajax: { url: '{{ url_for('main.api_db', collection='contracts') }}', dataSrc: 'data', type: 'GET', data: function (args) { //args.qString = getQuerystring(); //add in querystring args, or anything else you want return { "args": JSON.stringify(args) }; } }, columns: [ {data: 'ExpiryDate'}, {data: 'ContractId'}, {data: 'Vendor'}, {data: 'Note'} ] }); }); // in case you want to pass the querystring along with the request function getQuerystring() { var $qItems = $('#qItems'); $qItems.empty(); var hash; var filters = {}; var q = document.URL.split('?')[1]; if (q != undefined) { q = q.split('&'); for (var i = 0; i < q.length; i++) { hash = q[i].split('='); filters[hash[0]] = hash[1]; } } return filters } </script> {% endblock %}
In your views.py
:
import json from datetime import datetime, timedelta from mongo_datatables import Editor, DataTables from flask import request from app import mongo from . import main @main.route('/support-expiry', methods=['GET']) def support_expiry(): """This examples receives a 'daysToExpiry' value and translates it to an Expiration Date, which can be looked up in the Mongo collection. """ request_args = json.loads(request.values.get("args")) custom_filter = {} # translate daysToExpiry into a filter for the ExpiryDate Mongo key if 'daysToExpiry' in request_args['qString']: days_to_expiry = request_args['qString'].pop('daysToExpiry', None) # remove daysToExpiry, leave the rest t = datetime.utcnow() ts = t.strftime("%Y-%m-%d") if days_to_expiry == 'Expired': custom_filter.update({ 'ExpiryDate': {'$lt': ts, '$ne': ''} # ExpiryDate is before today but not equal to '' }) else: d = t + timedelta(days=int(days_to_expiry)) ds = d.strftime("%Y-%m-%d") custom_filter.update({ 'ExpiryDate': {'$gt': ts, '$lt': ds} # ExpiryDate is between now and daysToExpiry from now }) # add the rest of the query string to the custom filter custom_filter.update(request_args['qString']) collection = 'HardwareInventory' results = DataTables(mongo, collection, request_args, **custom_filter).get_rows() return json.dumps(results)
In your views.py
:
import json from flask import request from mongo_datatables import DataTables, Editor from . import main from app import mongo # include the table_view and api_db views from above @main.route('/mongo/edit/<collection>/<doc_id>', methods=['POST']) def api_editor(collection, doc_id): request_args = json.loads(request.values.get("args")) results = Editor(mongo, collection, request_args, doc_id).update_rows() return json.dumps(results)
In your table-view.html
:
{% extends "base.html" %} {% block content %} {{ super() }} <div class="container"> <table id="dt_table" class="table table-striped table-responsive"> <thead> <tr> <th>ExpiryDate</th> <th>ContractId</th> <th>Vendor</th> <th>Note</th> </tr> </thead> </table> </div> {% endblock %} {% block scripts %} {{ super() }} // DataTables, Editor, jQuery, Bootstrap, Buttons loaded here <script> $(function () { // DataTables var table = $('#dt_table').DataTable({ serverSide: true, ajax: { url: '{{ url_for('main.api_db', collection='contracts') }}', dataSrc: 'data', type: 'GET', data: function (args) { return { "args": JSON.stringify(args) }; } }, select: true, columns: [ {data: 'ExpiryDate'}, {data: 'ContractId'}, {data: 'Vendor'}, {data: 'Note'} ] }); // Editor var editor = new $.fn.dataTable.Editor({ ajax: { //Editor replaces _id_ with the row ID(s) (the Mongo _id(s)) url: '{{ url_for('main.api_editor', collection='contracts', doc_id='_id_') }}', type: 'POST', data: function (args) { return { "args": JSON.stringify(args) }; } }, table: "#dt_table", fields: [ {name: 'ExpiryDate', value: 'Expiry Date'}, {name: 'ContractId', value: 'Contract ID'}, {name: 'Vendor', value: 'Vendor'}, {name: 'Note', value: 'Note'} ] }); // Buttons new $.fn.dataTable.Buttons(table, [ {extend: "create", editor: editor}, {extend: "edit", editor: editor}, {extend: "remove", editor: editor} ]); table.buttons().container() .appendTo($(table.table().container(), '.col-sm-6:eq(0)')); }); </script> {% endblock %}