text: from os import sep
  import os.path
  import re
  
  import django
  from django.views.generic import View, TemplateView
  from django.conf import settings
  from django.core.urlresolvers import reverse
  from django.template.defaultfilters import timesince
  
  import datatableview
  from datatableview.views import DatatableView, XEditableDatatableView
  from datatableview.utils import get_datatable_structure
  from datatableview import helpers
  
  from .models import Entry, Blog
  
  class ResetView(View):
      """ Google App Engine view for reloading the database to a fresh state every 24 hours. """
      def get(self, request, *args, **kwargs):
          from django.core.management import call_command
          from django.http import HttpResponse
          call_command('syncdb')
          return HttpResponse("Done.")
  
  
  class IndexView(TemplateView):
      template_name = "index.html"
  
      def get_context_data(self, **kwargs):
          context = super(IndexView, self).get_context_data(**kwargs)
  
          # Try to determine if the user jumped the gun on testing things out
          db_works = True
          try:
              list(Entry.objects.all()[:1])
          except:
              db_works = False
          context['db_works'] = db_works
  
          path, working_directory = os.path.split(os.path.abspath('.'))
          context['working_directory'] = working_directory
          context['os_sep'] = sep
  
          # Versions
          context.update({
              'datatableview_version': '.'.join(map(str, datatableview.__version_info__)),
              'django_version': django.get_version(),
              'datatables_version': '1.10.0',
          })
  
          return context
  
  
  class JavascriptInitializationView(TemplateView):
      template_name = "javascript_initialization.html"
  
  
  class ValidColumnFormatsView(TemplateView):
      template_name = "valid_column_formats.html"
  
  
  class DemoMixin(object):
      description = """Missing description!"""
      implementation = """Missing implementation details!"""
  
      def get_template_names(self):
          """ Try the view's snake_case name, or else use default simple template. """
          name = self.__class__.__name__.replace("DatatableView", "")
          name = re.sub(r'([a-z]|[A-Z]+)(?=[A-Z])', r'\1_', name)
          return ["demos/" + name.lower() + ".html", "example_base.html"]
  
      def get_context_data(self, **kwargs):
          context = super(DemoMixin, self).get_context_data(**kwargs)
          context['implementation'] = self.implementation
  
          # Unwrap the lines of description text so that they don't linebreak funny after being put
          # through the ``linebreaks`` template filter.
          alert_types = ['info', 'warning', 'danger']
          paragraphs = []
          p = []
          alert = False
          for line in self.__doc__.splitlines():
              line = line[4:].rstrip()
              if not line:
                  if alert:
                      p.append(u"""</div>""")
                      alert = False
                  paragraphs.append(p)
                  p = []
              elif line.lower()[:-1] in alert_types:
                  p.append(u"""<div class="alert alert-{type}">""".format(type=line.lower()[:-1]))
                  alert = True
              else:
                  p.append(line)
          description = "\n\n".join(" ".join(p) for p in paragraphs)
          context['description'] = re.sub(r'``(.*?)``', r'<code>\1</code>', description)
  
          return context
  
  class ZeroConfigurationDatatableView(DemoMixin, DatatableView):
      """
      If no columns are specified in the view's ``datatable_options`` attribute, ``DatatableView``
      will use all of the model's local fields. Note that this does not include reverse
      relationships, many-to-many fields (even if the ``ManyToManyField`` is defined on the model
      directly), or the special ``pk`` field.
  
      Note that fields will attempt to use their ``verbose_name``, if available.
  
      WARNING:
      Having ``ForeignKey`` as a visible column will generate extra queries per displayed row, due to
      the way attribute lookup will cause Django to go fetch the related object. Implement a
      ``get_queryset()`` method on your view that returns a queryset with the appropriate call to
      ``select_related()``.
      """
  
      model = Entry
      datatable_options = {}
  
      implementation = u"""
      class ZeroConfigurationDatatableView(DatatableView):
          model = Entry
      """
  
  class SpecificColumnsDatatableView(DemoMixin, DatatableView):
      """
      To target specific columns that should appear on the table, use the
      ``datatable_options['columns']`` key in the configuration.  Specify a tuple or list of model
      field names, in the order that they are to appear on the table.
      
      Note that fields will attempt to use their ``verbose_name``, if available.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              'blog',
              'pub_date',
          ]
      }
  
      implementation = u"""
      class SpecificColumnsDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  'blog',
                  'pub_date',
              ]
          }
      """
  
  class PrettyNamesDatatableView(DemoMixin, DatatableView):
      """
      By converting a column's definition to a 2-tuple, you can specify a verbose name that should
      appear as the column header.  In this example, the ``pub_date`` field has been given a special
      verbose name ``"Publication date"``.
      
      This becomes particularly useful when the field is virtualized (i.e., not tied to a specific
      model field).
      """
      model = Entry
      datatable_options = {
          'columns': [
              'blog',
              'headline',
              ("Publication date", 'pub_date'),
              'n_comments',
              'rating',
          ]
      }
  
      implementation = u"""
      class PrettyNamesDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'blog',
                  'headline',
                  ("Publication date", 'pub_date'),
                  'n_comments',
                  'rating',
              ]
          }
      """
  
  
  class PresentationalChangesDatatableView(DemoMixin, DatatableView):
      """
      This table actually uses the same column twice; the first time is for a raw display of the
      ``pub_date`` value, and the second is for a humanized version of the same information via the
      template filter ``timesince``.
      
      Note that the ``Age`` column is sortable using the underlying data from the ``pub_date`` field,
      and is not actually sorting the presentionally modified text of the frontend.
  
      Callbacks should take the ``instance`` represented by the row, and ``*args`` and ``**kwargs``
      to maximize flexibility with future data arguments sent by the callback dispatcher.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'blog',
              'headline',
              ("Publication date", 'pub_date'),
              ("Age", 'pub_date', 'get_entry_age'),
          ],
      }
  
      def get_entry_age(self, instance, *args, **kwargs):
          return timesince(instance.pub_date)
  
      implementation = u"""
      from django.template.defaultfilters import timesince
      class PresentationalChangesDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'blog',
                  'headline',
                  ("Publication date", 'pub_date'),
                  ("Age", 'pub_date', 'get_entry_age'),
              ],
          }
  
          def get_entry_age(self, instance, *args, **kwargs):
              return timesince(instance.pub_date)
      """
  
  
  class VirtualColumnDefinitionsDatatableView(DemoMixin, DatatableView):
      """
      Columns that have values derived at runtime by callbacks located on the view should specify
      their field as ``None``, and then provide a callback name or function reference.
  
      Callbacks should take the ``instance`` represented by the row, and ``*args`` and ``**kwargs``
      to maximize flexibility with future data arguments sent by the callback dispatcher.
  
      Callbacks can be used for concrete fields too.
  
      INFO:
      The ``Age`` column could actually still specify its model field as ``pub_date``, but it was
      omitted specifically to demonstrate the bridging of the gap by the callback.  In this situation,
      the column is not searchable or sortable at the database level.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'blog',
              'headline',
              ("Age", None, 'get_entry_age'),
          ],
      }
  
      def get_entry_age(self, instance, *args, **kwargs):
          return timesince(instance.pub_date)
  
      implementation = u"""
      from django.template.defaultfilters import timesince
      class VirtualColumnDefinitionsDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'blog',
                  'headline',
                  ("Age", None, 'get_entry_age'),
              ],
          }
  
          def get_entry_age(self, instance, *args, **kwargs):
              return timesince(instance.pub_date)
      """
  
  
  class ColumnBackedByMethodDatatableView(DemoMixin, DatatableView):
      """
      Model methods can power columns instead of concrete fields.  This approach is similar to using
      a callback to supply a value for a virtual column, but demonstrates that non-field data sources
      may be used on the model without custom callbacks.
  
      In this situation, the ``pub_date`` is fetched using an example method ``get_pub_date()``. The
      column is technically sortable by default, but the operation takes place in code, rather than
      in the database.  Searching is not currently possible because of prohibitive performance
      penalties for large data sets.
  
      This strategy works nicely for fields that have a ``choices`` list, allowing you to use the
      ``get_FOO_display()`` method Django puts on the model instance.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'blog',
              'headline',
              ("Publication date", 'get_pub_date'),
          ],
      }
  
      implementation = """
      class ColumnBackedByMethodDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'blog',
                  'headline',
                  ("Publication date", 'get_pub_date'),  # get_pub_date is an attribute on the model
              ],
          }
      """
  
  
  class CompoundColumnsDatatableView(DemoMixin, DatatableView):
      """
      Simple columns might only need one model field to represent their data, even when marked up by
      a callback function.  However, if a column actually represents more than one model field, the
      list of those fields can be given in place of a single field name.
  
      INFO:
      You'll probably want to use a callback in order to decide how these values should be sorted out.
      The default strategy if no callback is supplies is to join the values with ``" "``.  The utility
      of this might be limited, but it's a reasonable default to give you a starting point.
  
      Compound columns should target fields, not merely foreign keys.  For example, you might indeed
      want the ``unicode(entry.blog)`` representation to appear in the marked-up column data, but be
      sure to target the specific fields on ``Blog`` that are represented in that display.
  
      Specifying all of the relevent fields in a compound column helps make searching and sorting more
      natural.  Sorting a compound column is the same as giving the field list to a call to the
      queryset ``order_by()`` method.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              ("Headline", ['headline', 'blog__name'], 'get_headline_data'),
          ],
      }
  
      def get_headline_data(self, instance, *args, **kwargs):
          return "%s (%s)" % (instance.headline, instance.blog.name)
  
      implementation = u"""
          class CompoundColumnDatatableView(DatatableView):
              model = Entry
              datatable_options = {
                  'columns': [
                      'id',
                      ("Headline", ['headline', 'blog__name'], 'get_headline_data'),
                  ],
              }
  
              def get_headline_data(self, instance, *args, **kwargs):
                  return "%s (%s)" % (instance.headline, instance.blog.name)
  
      """
  
  
  class RelatedFieldsDatatableView(DemoMixin, DatatableView):
      """
      The standard ``"__"`` related field syntax is supported in the model field names for a column.
      The only limitation is that the field's pretty-name should be explicitly given.
      
      Sorting, searching, and value callbacks work on these columns as well.
  
      INFO:
      When a value callback is used on a column, it receives the row's ``instance``, and various
      keyword arguments to give the callback some context about the value.  Callbacks always receive
      an argument ``default_value``, which is the value as fetched from the target field.  You can
      leverage this to avoid recalculating the same value from attribute lookups in your callbacks.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              ("Blog name", 'blog__name'),
              ("Blog ID", 'blog__id'),
              'pub_date',
          ],
      }
      
      implementation = u"""
      class RelatedFieldsDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  ("Blog name", 'blog__name'),
                  ("Blog ID", 'blog__id'),
                  'pub_date',
              ],
          }
      """
  
  
  class ManyToManyFieldsDatatableView(DemoMixin, DatatableView):
      """
      ``ManyToManyField`` relationships should not be specified directly as a column's data source.
      There's too much missing information, and the field name or field list should enumerate the
      real data points that are being shown.
  
      The most straightforward way to reveal a plural set of objects is to create your own callback
      handler that handles each item in the relationship as you see fit.  For example, combined with
      the ``helpers`` module, you can quickly make links out of the objects in the relationship.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              ("Authors", 'authors__name', 'get_author_names'),
              ("Authors", 'authors__name', 'get_author_names_as_links'),
          ],
      }
  
      def get_author_names(self, instance, *args, **kwargs):
          return ", ".join([author.name for author in instance.authors.all()])
  
      def get_author_names_as_links(self, instance, *args, **kwargs):
          return ", ".join([helpers.link_to_model(author) for author in instance.authors.all()])
  
      implementation = u"""
      class ManyToManyFields(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  ("Authors", 'authors__name', 'get_author_names'),
                  ("Authors", 'authors__name', 'get_author_names_as_links'),
              ],
          }
  
          def get_author_names(self, instance, *args, **kwargs):
              return ", ".join([author.name for author in instance.authors.all()])
  
          def get_author_names_as_links(self, instance, *args, **kwargs):
              from datatableview import helpers
              return ", ".join([helpers.link_to_model(author) for author in instance.authors.all()])
      """
  
  class DefaultCallbackNamesDatatableView(DemoMixin, DatatableView):
      """
      If a column definition hasn't supplied an explicit callback value processor, there is a default
      method that will be looked up on the view instance in the format of ``get_column_FOO_data()``.
  
      If the field has defined a "pretty name" in the tuple format, the pretty name will be used for
      the basis of looking up this default callback.  This is to avoid the complexities of mangling an
      automatic name that makes sense for compound and virtual columns.
      
      "Pretty names" put through the mangling process essentially normalize non-letter non-number
      characters to underscores, and multiple adjacent underscores are collapsed to a single
      underscore.  It's like a slugify process, but using ``"_"`` and without lowercasing.
  
      If the name mangling is ever unintuitive or cumbersome to remember or guess, you can either
      supply your own callback names as the third item in a column's 3-tuple definition, or else
      define a callback using the 0-based index instead of the field name, such as
      ``get_column_0_data()``.
  
      INFO:
      The default hook is only executed if there is no callback already supplied in the column
      definition.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              'body_text',
              'blog',
              ("Publication Date", 'pub_date'),
          ],
      }
  
      def get_column_body_text_data(self, instance, *args, **kwargs):
          return instance.body_text[:30]
  
      def get_column_Publication_Date_data(self, instance, *args, **kwargs):
          return instance.pub_date.strftime("%m/%d/%Y")
  
      implementation = u"""
      class DefaultCallbackNamesDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  'body_text',
                  'blog',
                  ("Publication Date", 'pub_date'),
              ],
          }
  
          def get_column_body_text_data(self, instance, *args, **kwargs):
              return instance.body_text[:30]
  
          def get_column_Publication_Date_data(self, instance, *args, **kwargs):
              return instance.pub_date.strftime("%m/%d/%Y")
      """
  
  class XEditableColumnsDatatableView(DemoMixin, XEditableDatatableView):
      """
      The <a href="http://vitalets.github.io/x-editable/">x-editable</a> javascript tool is a way to
      turn table cells into interactive forms that can post incremental updates over ajax.  x-editable
      supports Bootstrap, jQueryUI, and plain jQuery.  It requires its own specific initialization to
      take place after the datatable has populated itself with data.
  
      To enable x-editable columns, inherit your view from ``XEditableDatatableView`` instead of the
      plain ``DatatableView``.  The x-editable variant has ajax responders built into it so that the
      incremental updates can be received, validated, and responded to.  Choices lists are also
      fetched over ajax by the x-editable Javascript library, so this specialized view also responds
      to those.
  
      Next, use the ``datatableview.helpers.make_xeditable`` function as a callback for the columns
      that should become interactive.  You can customize the helper's behavior, but by default,
      ``make_xeditable`` will try to pick reasonable defaults for the field type.  This callback
      returns a ``&lt;a&gt;`` tag with ``data-*`` API attributes on it that the x-editable javascript
      knows how to read.
  
      Finally, on your template you will need to include a special initialization to make sure that
      the frontend understands how to handle what you've set up.  The global Javascript object
      ``datatableview`` has a member called ``make_xeditable`` (named after the helper function you
      use in the column definitions), which is a factory that returns a callback for the dataTables.js
      ``fnRowCallback`` hook.  See the implementation snippets below.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              ("Headline", 'headline', helpers.make_xeditable),
              ("Blog", 'blog', helpers.make_xeditable),
              ("Published date", 'pub_date', helpers.make_xeditable),
          ]
      }
  
      implementation = u"""
      class XEditableColumnsDatatableView(XEditableDatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  ("Headline", 'headline', helpers.make_xeditable),
                  ("Blog", 'blog', helpers.make_xeditable),
                  ("Published date", 'pub_date', helpers.make_xeditable),
              ]
          }
      </pre>
      <pre class="brush: javascript">
      // Page javascript
      datatableview.auto_initialize = false;
      $(function(){
          var xeditable_options = {};
          datatableview.initialize($('.datatable'), {
              fnRowCallback: datatableview.make_xeditable(xeditable_options),
          });
      })
      """
  
  
  class HelpersReferenceDatatableView(DemoMixin, XEditableDatatableView):
      """
      ``datatableview.helpers`` is a module decidated to functions that can be supplied directly as
      column callback functions.  Some of them are easy to use at runtime in your own callbacks,
      making some work easier for you, but the majority aim to solve common problems with as little
      fuss as possible.
      """
      model = Entry
      datatable_options = {
          'columns': [
              ("ID", 'id', helpers.link_to_model),
              ("Blog", 'blog__name', helpers.link_to_model(key=lambda instance: instance.blog)),
              ("Headline", 'headline', helpers.make_xeditable),
              ("Body Text", 'body_text', helpers.itemgetter(slice(0, 30))),
              ("Publication Date", 'pub_date', helpers.format_date('%A, %b %d, %Y')),
              ("Modified Date", 'mod_date'),
              ("Age", 'pub_date', helpers.through_filter(timesince)),
              ("Interaction", 'get_interaction_total', helpers.make_boolean_checkmark),
              ("Comments", 'n_comments', helpers.format("{0:,}")),
              ("Pingbacks", 'n_pingbacks', helpers.format("{0:,}")),
          ],
      }
  
      implementation = u"""
      class HelpersReferenceDatatableView(XEditableDatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  ("ID", 'id', helpers.link_to_model),
                  ("Blog", 'blog__name', helpers.link_to_model(key=lambda instance: instance.blog)),
                  ("Headline", 'headline', helpers.make_xeditable),
                  ("Body Text", 'body_text', helpers.itemgetter(slice(0, 30))),
                  ("Publication Date", 'pub_date', helpers.format_date('%A, %b %d, %Y')),
                  ("Modified Date", 'mod_date'),
                  ("Age", 'pub_date', helpers.through_filter(timesince)),
                  ("Interaction", 'get_interaction_total', helpers.make_boolean_checkmark),
                  ("Comments", 'n_comments', helpers.format("{0:,}")),
                  ("Pingbacks", 'n_pingbacks', helpers.format("{0:,}")),
              ],
          }
      """
  
  
  class PerRequestOptionsDatatableView(DemoMixin, DatatableView):
      """
      Care must be taken to modify the options object on the View class: because it is defined as a
      class attribute, there is only one copy of it in memory, and changing it is not thread safe.
      
      To safely change the options at runtime, copy the main options dictionary and then make a deep
      of the columns list (copying the outer dictionary will not do this automatically).  The simplest
      way to do this is via a call to the built-in ``copy.deepcopy`` function.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
          ],
      }
  
      def get_datatable_options(self):
          from copy import deepcopy
          options = deepcopy(self.datatable_options)
          options['columns'].append("blog")
          return options
  
      implementation = u"""
      class PerRequestOptionsDatatableView(DemoMixin, DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
              ],
          }
  
          def get_datatable_options(self):
              from copy import deepcopy
              options = deepcopy(self.datatable_options)
              options['columns'].append("blog")
              return options
      """
  
  class OrderingDatatableView(DemoMixin, DatatableView):
      """
      Default ordering is normally controlled by the model's Meta option ``ordering``, which is a list
      of field names (possibly with a prefix ``"-"`` character to denote reverse order).
      
      ``datatable_options["ordering"]`` is the same kind of list, with the exception that it should
      target virtual and compound fields by their "pretty name", which is the first item in the column
      definition tuple.
      """
      model = Entry
      datatable_options = {
          'columns': [
              ("Pretty name", 'id'),
              'headline',
          ],
          'ordering': ['-id'],
      }
  
      implementation = u"""
      class OrderingDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
              ],
              'ordering': ['-id'],
          }
      """
  
  
  class UnsortableColumnsDatatableView(DemoMixin, DatatableView):
      """
      Columns that should be blocked from sorting (on the frontend and also by the backend) can be
      enumerated in the ``datatable_options['unsortable_columns']`` key.
  
      When the table structure is initially rendered onto the page, the ``&lt;th&gt;`` elements are
      given attributes in a ``data-*`` API fashion.  (dataTables.js does not actually support this
      API, but it greatly simplifies the legwork required to get a table automatically initialized.)
      For sorting, the data attribute is ``data-sortable``, the value being ``"true"`` by default,
      but ``"false"`` if the column name is given in the unsortable columns list.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              'blog',
              'pub_date',
          ],
          'unsortable_columns': ['headline', 'blog', 'pub_date'],
      }
  
      implementation = u"""
      class UnsortableColumnsDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  'body_text',
                  'blog',
                  'pub_date',
              ],
              'unsortable_columns': ['headline', 'body_text', 'blog', 'pub_date'],
          }
      """
  
  
  class HiddenColumnsDatatableView(DemoMixin, DatatableView):
      """
      Columns may be marked for being hidden.  This is a client-side tweak that has no benefit to
      server performance.  When dataTables.js sees a column marked for being hidden, it removes it
      from the DOM, but retains traces of it in memory.  Some of the dataTables.js plugins have used
      this to allow you to send columns that are invisible on the main website, but if exported to
      CSV by the client, are included and visible as usual.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              'blog',
              'pub_date',
          ],
          'hidden_columns': ['id'],
      }
  
      implementation = u"""
      class HiddenColumnsDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  'blog',
                  'pub_date',
              ],
              'hidden_columns': ['id'],
          }
      """
  
  
  class SearchFieldsDatatableView(DemoMixin, DatatableView):
      """
      When a user searches a datatable, the server will query all of the concrete fields in the
      displayed columns.  You can enable extra search fields that are not shown on the table, but are
      consulted during a search query, by adding ``datatable_options["search_fields"]``.
      
      ``search_fields`` is a simple list of fields using the normal query language.  In this case,
      ``"blog__name"`` has been added to the list of fields, and so you can search the above table
      for the term ``First`` or ``Second`` and see the table filter the results, even though that
      field is not included as a real column.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              'pub_date',
          ],
          'search_fields': ['blog__name'],
      }
  
      implementation = u"""
      class SearchFieldsDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  'pub_date',
              ],
              'search_fields': ['blog__name'],
          }
      """
  
  
  class CustomizedTemplateDatatableView(DemoMixin, DatatableView):
      """
      When the ``datatable`` context variable is rendered, it looks for a template named
      ``"datatableview/default_structure.html"``.  This template is pretty generic, but lacks special
      styles for UI frameworks like Twitter Bootstrap and others.
  
      The default template renders special ``data-*`` attributes on the ``table`` and ``th`` tags,
      which helps make initializing the tables more seamless when using the ``datatableview.js`` tool.
  
      Alternately, you can specify a custom template on a per-view basis using
      ``datatable_options["structure_template"]``, which is a normal template path that will be put
      through the Django discovery process.
  
      WARNING:
      When overriding this template, take care to render the ``data-*`` attributes if you want easy
      table initialization!
      """
      model = Entry
      datatable_options = {
          'structure_template': "custom_table_template.html",
          'columns': [
              'id',
              'headline',
              'blog',
              'pub_date',
          ],
      }
  
      implementation = u"""
      class CustomizedTemplateDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'structure_template': "custom_table_template.html",
              'columns': [
                  'id',
                  'headline',
                  'blog',
                  'pub_date',
              ],
          }
      """
  
  class BootstrapTemplateDatatableView(DemoMixin, DatatableView):
      """
      The easiest way to get Bootstrap datatables is to use the alternate structural template
      ``datatableview/bootstrap_structure.html``, which simply adds the
      ``table``, ``table-striped``, and ``table-bordered`` classes to the main table tag.  You can
      specify the template directly in ``datatable_options["structure_template"]``, or you can create
      your own ``datatableview/default_structure.html`` template and simply paste the contents of the
      bootstrap version into it.
      
      WARNING:
      Overriding ``datatableview/default_structure.html`` will affect all datatables using the default
      template!
  
      This gets the table itself looking better, but the rest of the controls added by dataTables.js
      are a little lackluster by comparison.  To fix this, reference the latest integration helper CSS
      and javascript support files in the template:
      
      <pre>
      &lt;link href="//cdn.datatables.net/plug-ins/be7019ee387/integration/bootstrap/3/dataTables.bootstrap.css" rel="stylesheet" /&gt;
      </pre>
      <pre>
      &lt;script src="//cdn.datatables.net/plug-ins/be7019ee387/integration/bootstrap/3/dataTables.bootstrap.js"&gt;&lt;/script&gt;
      </pre>
  
      See <a href="https://datatables.net/examples/styling/bootstrap.html">the official datatables
      documentation</a> on the subject for more information.
  
      WARNING:
      The pagination buttons are currently a bit strange with Bootstrap 3.1.1 and Datatables 1.10.0.
      Please make sure you are using the latest integration files by checking the link just above.
      """
      model = Entry
      datatable_options = {
          'structure_template': "datatableview/bootstrap_structure.html",
          'columns': [
              'id',
              'headline',
              'blog',
              'pub_date',
          ],
      }
  
      implementation = u"""
      class BootstrapTemplateOfficialDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'structure_template': "datatableview/bootstrap_structure.html",
              'columns': [
                  'id',
                  'headline',
                  'blog',
                  'pub_date',
              ],
          }
      """
  
  
  class CSSStylingDatatableView(DemoMixin, DatatableView):
      """
      The default template used by the datatable context variable when you render it will include
      ``data-name`` attributes on the ``&lt;th&gt;`` column headers, which is the ``slugify``'d
      version of the column's label.  This makes sizing the columns very easy.
      """
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              'blog',
              ("Publication date", 'pub_date'),
          ],
      }
  
      implementation = u"""
      class CSSStylingDatatableView(DatatableView):
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  'blog',
                  'pub_date',
              ],
          }
      """
  
  
  class MultipleTablesDatatableView(DemoMixin, DatatableView):
      """
      ``DatatableView`` makes the initial assumption that it will power just one queryset.  You can
      implement ``get_queryset()``, ``get_datatable_options()``, and ``get_datatable()`` methods that
      use switching behavior depending on which table is asking for updates. (More on how to flag
      that fact farther down.)
  
      WARNING:
      If more than one model class type might end up getting returned via the ``get_queryset()``
      method, as is the case in the following scenario, you should avoid setting the class attribute
      ``model``.  Instead, you can let the standard ``ListView`` mechanics that ``DatatableView`` uses
      automatically read the model class from the returned queryset from ``get_queryset()``.
  
      See the following examples for how to handle certain scenarios.
      
      The principle of the process is that you can override ``get_datatable_options()`` and
      ``get_datatable()`` to modify the structural objects that get returned by the view based on
      certain URL kwargs, GET data, etc.  If you examine the implementation code at the bottom of the
      page, you will see how these two methods have been customized to accept a ``type`` argument.
      This is used when the context data is originally fetched, so that we can request each table
      structure object.
  
      Once AJAX calls start happening on the page, each table structure needs to identify itself so
      that the view can deal with each one separately.  To accomplish this, our ``get_datatable()``
      implementation adds a GET parameter in the AJAX url for each table to distinguish them.  This
      parameter is fed back to us during AJAX calls.
  
      Finally, we can modify the ``get_queryset()`` method on the same principle; depending on the GET
      flag we've set up, the method should perhaps return customized content.
  
      Demo #1 in this series of examples is the default code path, where no modifications of any kind
      are at play.  Demo #2 slices off the ``"Header"`` column from the options of #1.  Demo #3 uses
      its own separate model and options.  All are identified separately in their AJAX queries by the
      variable we planted in each table's structure in ``get_context_data()``.
      """
  
      # Demo #1 and Demo # 2 will use variations of the same options.
      # Note that we're not setting the model here as usually.  See the warning above.
      datatable_options = {
          'columns': [
              'id',
              'headline',
          ],
      }
  
      # Demo #3 will use completely separate options.
      blog_datatable_options = {
          'columns': [
              'id',
              'name',
              'tagline',
          ],
      }
  
      def get_queryset(self, type=None):
          """
          Customized implementation of the queryset getter.  The custom argument ``type`` is managed
          by us, and is used in the context and GET parameters to control which table we return.
          """
  
          if type is None:
              type = self.request.GET.get('datatable-type', None)
  
          if type == "demo3":
              return Blog.objects.all()
          return Entry.objects.all()
  
      def get_datatable_options(self, type=None):
          """
          Customized implementation of the options getter.  The custom argument ``type`` is managed
          by us, and is used in the context and GET parameters to control which table we return.
          """
  
          if type is None:
              type = self.request.GET.get('datatable-type', None)
  
          options = self.datatable_options
  
          if type == "demo2":
              # If modifying the options, be sure make copies of the pieces you are changing, or else
              # you'll end up changing class-level definitions that are not thread-safe!
              options = self.datatable_options.copy()
              options['columns'] = options['columns'][1:]
          elif type == "demo3":
              # Return separate options settings
              options = self.blog_datatable_options
  
          return options
  
      def get_datatable(self, type=None):
          """
          Customized implementation of the structure getter.  The custom argument ``type`` is managed
          by us, and is used in the context and GET parameters to control which table we return.
          """
          if type is None:
              type = self.request.GET.get('datatable-type', None)
  
          if type is not None:
              datatable_options = self.get_datatable_options(type=type)
              # Put a marker variable in the AJAX GET request so that the table identity is known
              ajax_url = self.request.path + "?datatable-type={type}".format(type=type)
  
          if type == "demo2":
              datatable = get_datatable_structure(ajax_url, datatable_options, model=Entry)
          elif type == "demo3":
              # Change the reference model to Blog, instead of Entry
              datatable = get_datatable_structure(ajax_url, datatable_options, model=Blog)
          else:
              return super(MultipleTablesDatatableView, self).get_datatable()
  
          return datatable
          
  
      def get_context_data(self, **kwargs):
          context = super(MultipleTablesDatatableView, self).get_context_data(**kwargs)
      
          # Get the other structure objects for the initial context
          context['modified_columns_datatable'] = self.get_datatable(type="demo2")
          context['blog_datatable'] = self.get_datatable(type="demo3")
          return context
  
      implementation = u'''
      from .models import Entry, Blog
      class MultipleTablesDatatableView(DatatableView):
          # Demo #1 and Demo # 2 will use variations of the same options
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
              ],
          }
  
          # Demo #3 will use completely separate options
          blog_datatable_options = {
              'columns': [
                  'id',
                  'name',
                  'tagline',
              ],
          }
  
          def get_queryset(self, type=None):
              """
              Customized implementation of the queryset getter.  The custom argument ``type`` is managed
              by us, and is used in the context and GET parameters to control which table we return.
              """
  
              if type is None:
                  type = self.request.GET.get('datatable-type', None)
  
              if type == "demo3":
                  return Blog.objects.all()
              return super(MultipleTablesDatatableView, self).get_queryset()
  
          def get_datatable_options(self, type=None):
              """
              Customized implementation of the options getter.  The custom argument ``type`` is managed
              by us, and is used in the context and GET parameters to control which table we return.
              """
  
              if type is None:
                  type = self.request.GET.get('datatable-type', None)
  
              options = self.datatable_options
  
              if type == "demo2":
                  # If modifying the options, be sure make copies of the pieces you are changing, or else
                  # you'll end up changing class-level definitions that are not thread-safe!
                  options = self.datatable_options.copy()
                  options['columns'] = options['columns'][1:]
              elif type == "demo3":
                  # Return separate options settings
                  options = self.blog_datatable_options
  
              return options
  
          def get_datatable(self, type=None):
              """
              Customized implementation of the structure getter.  The custom argument ``type`` is managed
              by us, and is used in the context and GET parameters to control which table we return.
              """
              if type is None:
                  type = self.request.GET.get('datatable-type', None)
  
              if type is not None:
                  datatable_options = self.get_datatable_options(type=type)
                  # Put a marker variable in the AJAX GET request so that the table identity is known
                  ajax_url = self.request.path + "?datatable-type={type}".format(type=type)
  
              if type == "demo2":
                  datatable = get_datatable_structure(ajax_url, datatable_options, model=Blog)
              elif type == "demo3":
                  # Change the reference model to Blog, instead of Entry
                  datatable = get_datatable_structure(ajax_url, datatable_options, model=Entry)
              else:
                  return super(MultipleTablesDatatableView, self).get_datatable()
  
              return datatable
          
  
          def get_context_data(self, **kwargs):
              context = super(MultipleTablesDatatableView, self).get_context_data(**kwargs)
  
              # Get the other structure objects for the initial context
              context['modified_columns_datatable'] = self.get_datatable(type="demo2")
              context['blog_datatable'] = self.get_datatable(type="demo3")
              return context
      '''
  
  
  class EmbeddedTableDatatableView(DemoMixin, TemplateView):
      """
      To embed a datatable onto a page that shouldn't be responsible for generating all of the ajax
      queries, you can easily just create the structure object that serves as the context variable,
      but base it on the options of some other view.  The other view will indeed need access to those
      options once queries begin to autonomously route to it over AJAX, so you won't be able to
      specify the column options directly inside of the ``get_context_data()``, but you can get pretty
      close.
  
      In this example, we've created a separate view, called ``SatelliteDatatableView``, which houses
      all of the options and machinery for getting the structure object for the context.
  
      Just add a ``get_context_data()`` method, instantiate the other view, and ask it to generate
      the options object via ``get_datatable_options()``.  You can feed this options object into 
      the ``datatableview.utils.get_datatable_structure()`` utility.
      
      ``get_datatable_structure()`` takes at least two arguments, and is the mechanism that a regular
      call to a ``DatatableView.get_datatable()`` uses to get the context variable: the ``ajax_url``
      the table will target, and the ``options`` object.  Unless there are ordering options set in
      the main ``datatable_options`` object, the table won't know how to use default ordering, so you
      can specify the third optional argument ``model``.
      """
  
      def get_context_data(self, **kwargs):
          context = super(EmbeddedTableDatatableView, self).get_context_data(**kwargs)
  
          satellite_view = SatelliteDatatableView()
          model = satellite_view.model
          options = satellite_view.get_datatable_options()
          datatable = get_datatable_structure(reverse('satellite'), options, model=model)
  
          context['datatable'] = datatable
          return context
  
      implementation = u'''
      class EmbeddedTableDatatableView(TemplateView):
          def get_context_data(self, **kwargs):
              context = super(EmbeddedTableDatatableView, self).get_context_data(**kwargs)
  
              satellite_view = SatelliteDatatableView()
              model = satellite_view.model
              options = satellite_view.get_datatable_options()
              datatable = get_datatable_structure(reverse('satellite'), options, model=model)
  
              context['datatable'] = datatable
              return context
  
      class SatelliteDatatableView(DatatableView):
          """
          External view powering the embedded table for ``EmbeddedTableDatatableView``.
          """
          model = Entry
          datatable_options = {
              'columns': [
                  'id',
                  'headline',
                  'pub_date',
              ],
          }
      '''
  
  class SatelliteDatatableView(DatatableView):
      """
      External view powering the embedded table for ``EmbeddedTableDatatableView``.
      """
      template_name = "blank.html"
      model = Entry
      datatable_options = {
          'columns': [
              'id',
              'headline',
              'pub_date',
          ],
      }
  