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