/template_utils/templatetags/generic_content.py

http://django-template-utils.googlecode.com/ · Python · 157 lines · 120 code · 15 blank · 22 comment · 2 complexity · 4a224a5bcaadc7572c75bcab82c9cab6 MD5 · raw file

  1. """
  2. Template tags which can do retrieval of content from any model.
  3. """
  4. from django import template
  5. from django.db.models import get_model
  6. from template_utils.nodes import ContextUpdatingNode, GenericContentNode
  7. class RandomObjectsNode(GenericContentNode):
  8. """
  9. A subclass of ``GenericContentNode`` which overrides
  10. ``_get_query_set`` to apply random ordering.
  11. """
  12. def _get_query_set(self):
  13. return self.query_set.order_by('?')
  14. class RetrieveObjectNode(ContextUpdatingNode):
  15. """
  16. ``Node`` subclass which retrieves a single object -- by
  17. primary-key lookup -- from a given model.
  18. Because this is a primary-key lookup, it is assumed that no other
  19. filtering is needed; hence, the settings-based filtering performed
  20. by ``GenericContentNode`` is not used here.
  21. """
  22. def __init__(self, model, pk, varname):
  23. self.pk = template.Variable(pk)
  24. self.varname = varname
  25. self.model = get_model(*model.split('.'))
  26. if self.model is None:
  27. raise template.TemplateSyntaxError("Generic content tag got invalid model: %s" % model)
  28. def get_content(self, context):
  29. return { self.varname: self.model._default_manager.get(pk=self.pk.resolve(context))}
  30. def do_latest_object(parser, token):
  31. """
  32. Retrieves the latest object from a given model, in that model's
  33. default ordering, and stores it in a context variable.
  34. Syntax::
  35. {% get_latest_object [app_name].[model_name] as [varname] %}
  36. Example::
  37. {% get_latest_object comments.freecomment as latest_comment %}
  38. """
  39. bits = token.contents.split()
  40. if len(bits) != 4:
  41. raise template.TemplateSyntaxError("'%s' tag takes three arguments" % bits[0])
  42. if bits [2] != 'as':
  43. raise template.TemplateSyntaxError("second argument to '%s' tag must be 'as'" % bits[0])
  44. return GenericContentNode(bits[1], 1, bits[3])
  45. def do_latest_objects(parser, token):
  46. """
  47. Retrieves the latest ``num`` objects from a given model, in that
  48. model's default ordering, and stores them in a context variable.
  49. Syntax::
  50. {% get_latest_objects [app_name].[model_name] [num] as [varname] %}
  51. Example::
  52. {% get_latest_objects comments.freecomment 5 as latest_comments %}
  53. """
  54. bits = token.contents.split()
  55. if len(bits) != 5:
  56. raise template.TemplateSyntaxError("'%s' tag takes four arguments" % bits[0])
  57. if bits [3] != 'as':
  58. raise template.TemplateSyntaxError("third argument to '%s' tag must be 'as'" % bits[0])
  59. return GenericContentNode(bits[1], bits[2], bits[4])
  60. def do_random_object(parser, token):
  61. """
  62. Retrieves a random object from a given model, and stores it in a
  63. context variable.
  64. Syntax::
  65. {% get_random_object [app_name].[model_name] as [varname] %}
  66. Example::
  67. {% get_random_object comments.freecomment as random_comment %}
  68. """
  69. bits = token.contents.split()
  70. if len(bits) != 4:
  71. raise template.TemplateSyntaxError("'%s' tag takes three arguments" % bits[0])
  72. if bits [2] != 'as':
  73. raise template.TemplateSyntaxError("second argument to '%s' tag must be 'as'" % bits[0])
  74. return RandomObjectsNode(bits[1], 1, bits[3])
  75. def do_random_objects(parser, token):
  76. """
  77. Retrieves ``num`` random objects from a given model, and stores
  78. them in a context variable.
  79. Syntax::
  80. {% get_random_objects [app_name].[model_name] [num] as [varname] %}
  81. Example::
  82. {% get_random_objects comments.freecomment 5 as random_comments %}
  83. """
  84. bits = token.contents.split()
  85. if len(bits) != 5:
  86. raise template.TemplateSyntaxError("'%s' tag takes four arguments" % bits[0])
  87. if bits [3] != 'as':
  88. raise template.TemplateSyntaxError("third argument to '%s' tag must be 'as'" % bits[0])
  89. return RandomObjectsNode(bits[1], bits[2], bits[4])
  90. def do_retrieve_object(parser, token):
  91. """
  92. Retrieves a specific object from a given model by primary-key
  93. lookup, and stores it in a context variable.
  94. Syntax::
  95. {% retrieve_object [app_name].[model_name] [pk] as [varname] %}
  96. Example::
  97. {% retrieve_object flatpages.flatpage 12 as my_flat_page %}
  98. """
  99. bits = token.contents.split()
  100. if len(bits) != 5:
  101. raise template.TemplateSyntaxError("'%s' tag takes four arguments" % bits[0])
  102. if bits[3] != 'as':
  103. raise template.TemplateSyntaxError("third argument to '%s' tag must be 'as'" % bits[0])
  104. return RetrieveObjectNode(bits[1], bits[2], bits[4])
  105. register = template.Library()
  106. register.tag('get_latest_object', do_latest_object)
  107. register.tag('get_latest_objects', do_latest_objects)
  108. register.tag('get_random_object', do_random_object)
  109. register.tag('get_random_objects', do_random_objects)
  110. register.tag('retrieve_object', do_retrieve_object)