/views.py

https://github.com/aidaho/djax · Python · 106 lines · 80 code · 2 blank · 24 comment · 7 complexity · 8a7960013909652b54f3fb4a9f8e4b84 MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. """
  3. Django AJAX - Server-side companion for client-side ajax javascript.
  4. Provides custom view class designed to be drop-in replacement
  5. for TemplateView in Django 1.5 and higher.
  6. Copyright (C) 2013 Sergey Frolov
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License v3
  9. or BSD 2-clause license.
  10. Here follows 'no warranty' rattle, you know the drill.
  11. """
  12. from django.views.generic.base import TemplateResponseMixin, ContextMixin, View
  13. try:
  14. from settings import AJAX_TEMPLATE_POSTFIX
  15. except ImportError:
  16. AJAX_TEMPLATE_POSTFIX = "-ajax"
  17. try:
  18. from settings import AJAX_HTTP_HEADER
  19. except ImportError:
  20. AJAX_HTTP_HEADER = "HTTP_X_PJAX" # default header for jquery-pjax
  21. class AjaxTemplateMixin(TemplateResponseMixin):
  22. """
  23. Ajax-related template heuristic.
  24. In case of presence AJAX_HTTP_HEADER in request returns either
  25. self.ajax_template_name or tuple of guessed ajax template and
  26. template_name. Django will render the first one available so it's
  27. safe to use this class even if no ajax template available for this
  28. view.
  29. """
  30. ajax_template_name = None
  31. def trigger_ajax_response(self):
  32. """Override this for setting custom trigger conditions"""
  33. return self.request.META.get(AJAX_HTTP_HEADER, False)
  34. def get_ajax_template_postfix(self):
  35. """Return template postfix for ajax response"""
  36. return AJAX_TEMPLATE_POSTFIX
  37. def get_template_names(self):
  38. names = super(AjaxTemplateMixin, self).get_template_names()
  39. if self.trigger_ajax_response():
  40. if not self.ajax_template_name:
  41. def guess_template(name):
  42. """
  43. Appends postfix either before the template file extension
  44. or after template file name if one lacks extension.
  45. Example:
  46. >>> AJAX_TEMPLATE_POSTFIX = "-ajax"
  47. >>> guess_template('filename.ext')
  48. 'filename-ajax.ext'
  49. >>> guess_template('filename')
  50. 'filename-ajax'
  51. """
  52. if "." in name:
  53. splitname = name.split('.')
  54. splitname[-2] += self.get_ajax_template_postfix()
  55. ajax_name = '.'.join(splitname)
  56. else:
  57. ajax_name = name + self.get_ajax_template_postfix()
  58. return ajax_name
  59. def roundrobin(*args):
  60. """
  61. Simple roundrobin. Truncates result at a length of the
  62. shortest supplied list/tuple.
  63. Example:
  64. >>> roundrobin([1,2,3], [4,5,6,7,8], [9])
  65. [1, 4, 9]
  66. """
  67. result = []
  68. i = min([len(arg) for arg in args])
  69. assert i > 0, "Zero-length iterable passed"
  70. while i:
  71. for arg in args:
  72. result.append(arg[i-1])
  73. i -= 1
  74. return result
  75. ajax_names = map(guess_template, names)
  76. names = roundrobin(ajax_names, names)
  77. else: # ajax_template_name is set
  78. names = [self.ajax_template_name]
  79. return names
  80. class AjaxSimpleTriggerMixin(object):
  81. """Fires ajax reply on any ajax request."""
  82. def trigger_ajax_response(self):
  83. return self.request.is_ajax()
  84. class AjaxTemplateView(AjaxTemplateMixin, ContextMixin, View):
  85. """
  86. Ajaxified Drop-in replacement for TemplateView.
  87. """
  88. def get(self, request, *args, **kwargs):
  89. context = self.get_context_data(**kwargs)
  90. return self.render_to_response(context)