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