kmike / django-faves

This app lets users favorite objects in your database (as well as unfavorite them). Original author is jeffrey.a.croft.

Clone this repository (size: 72.8 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/kmike/django-faves/

Changed (Δ1.8 KB):

raw changeset »

docs/overview.txt (26 lines added, 1 lines removed)

faves/templatetags/faves.py (74 lines added, 31 lines removed)

setup.py (1 lines added, 1 lines removed)

Up to file-list docs/overview.txt:

@@ -46,7 +46,7 @@ Views:
46
46
Template filters:
47
47
48
48
 - has_faved
49
 - is_vavorited 
49
 - is_favorited 
50
50
51
51
Template tags:
52
52
@@ -56,6 +56,7 @@ Template tags:
56
56
 - get_faves_for_user
57
57
 - get_favorited
58
58
 - get_fave
59
 - inject_faves_to
59
60
 
60
61
61
62
@@ -126,3 +127,27 @@ You have 'details' page for 1 object. It
126
127
{% else %}
127
128
    <a href = '{% get_fave_url object "favorites" %}'>remove from favorites</a>
128
129
{% endif %}    
130
131
132
=== New in version 0.6.2 ===
133
134
`inject_faves_to` template tag is added. It is similar to `get_favorited` tag
135
but instead of setting context variable it adds attribute with Fave instance 
136
for each favorited object in `objects` list (iterable with django models).
137
    
138
Syntax::
139
140
	{% inject_faves_to [objects] by [user] of type [fave-type-slug] as [attribute_name] %}
141
142
Example::
143
144
	{% load faves %}
145
	{% inject_faves_to page.object_list by request.user of type favorites as fave %}
146
	
147
	{% for object in page.object_list %}
148
	    {{ object }}
149
	    {% if object.fave %}
150
	        favorited 
151
	    {% endif %}
152
	{% endfor %}
153
	

Up to file-list faves/templatetags/faves.py:

@@ -12,6 +12,24 @@ register = Library()
12
12
Fave = models.get_model('faves', 'fave')
13
13
FaveType = models.get_model('faves', 'favetype')
14
14
15
16
def validate_template_tag_params(bits, arguments_count, keyword_positions):
17
    '''
18
        Raises exception if passed params (`bits`) do not match signature.
19
        Signature is defined by `bits_len` (acceptible number of params) and
20
        keyword_positions (dictionary with positions in keys and keywords in values,
21
        for ex. {2:'by', 4:'of', 5:'type', 7:'as'}).            
22
    '''    
23
    
24
    if len(bits) != arguments_count+1:
25
        raise template.TemplateSyntaxError("'%s' tag takes %d arguments" % (bits[0], arguments_count,))
26
    
27
    for pos in keyword_positions:
28
        value = keyword_positions[pos]
29
        if bits[pos] != value:
30
            raise template.TemplateSyntaxError("argument #%d to '%s' tag must be '%s'" % (pos, bits[0], value))
31
        
32
    
15
33
@register.filter
16
34
def has_faved(value, arg):
17
35
    """
@@ -106,7 +124,9 @@ def get_unfave_url(object, fave_type_slu
106
124
    """
107
125
    try:
108
126
        content_type = ContentType.objects.get_for_model(object)
109
        return reverse('unfave_object', args=(fave_type_slug, content_type.id, object.id))
127
        return reverse('unfave_object', kwargs={'fave_type_slug': fave_type_slug, 
128
                                                'content_type_id': content_type.id,
129
                                                'object_id': object.id})
110
130
    except:
111
131
        return ''
112
132
@@ -125,7 +145,6 @@ class GetFavoritesForUserNode(template.N
125
145
                context[self.varname] = Fave.objects.active().filter(type__slug=self.fave_type_slug, user=user, content_type=content_type)
126
146
            else:    
127
147
                context[self.varname] = Fave.objects.active().filter(type__slug=self.fave_type_slug, user=user)
128
#            context[self.varname] = Fave.objects.active().filter(type__slug=self.fave_type_slug, user=user).values('id','content_type_id','object_id')
129
148
        except:
130
149
            pass
131
150
        return ''
@@ -162,25 +181,33 @@ def get_faves_for_user(parser, token):
162
181
        return GetFavoritesForUserNode(bits[1], bits[4], bits[5], bits[7])
163
182
164
183
165
166
184
class GetFavoritedNode(template.Node):
167
185
    def __init__(self, object_list, user, fave_type_slug, varname):
168
186
        self.object_list, self.user, self.fave_type_slug, self.varname = object_list, user, fave_type_slug, varname
187
        
188
    def return_results(self):
189
        context[self.varname] = self.faves_dict
169
190
170
191
    def render(self, context):
171
192
        try:
172
193
            user = resolve_variable(self.user, context)
173
            objects = resolve_variable(self.object_list, context) 
174
                        
175
            content_type = ContentType.objects.get_for_model(objects[0])
176
            id_values = [item.id for item in objects]
194
            self.objects = resolve_variable(self.object_list, context)                         
195
196
            ''' allow single object to be passed by putting it into list '''
197
            try:  
198
                it = iter(self.objects)
199
            except TypeError: 
200
                self.objects = [self.objects]
201
                
202
            content_type = ContentType.objects.get_for_model(self.objects[0])
177
203
            
178
204
            faves = Fave.objects.active().filter(type__slug=self.fave_type_slug, 
179
205
                                                 user=user, 
180
206
                                                 content_type=content_type,
181
                                                 object_id__in=id_values)
207
                                                 object_id__in=[item.id for item in self.objects])            
208
            self.faves_dict = dict((fave.object_id, fave) for fave in list(faves))            
182
209
            
183
            context[self.varname] = dict((fave.object_id,fave,) for fave in list(faves))
210
            self.return_results()
184
211
        except:
185
212
            pass
186
213
        return ''
@@ -210,17 +237,43 @@ def get_favorited(parser, token):
210
237
211
238
    """
212
239
    bits = token.contents.split()
240
    validate_template_tag_params(bits, 8, {2:'by', 4:'of', 5:'type', 7:'as'})
241
                
242
    return GetFavoritedNode(bits[1], bits[3], bits[6], bits[8])
243
244
245
246
class InjectFavesToNode(GetFavoritedNode):
247
    def return_results(self):
248
        for object in self.objects:
249
            if self.faves_dict.has_key(object.id):
250
                object.__setattr__(self.varname, self.faves_dict[object.id])        
251
252
@register.tag
253
def inject_faves_to(parser, token):
254
    """
255
    Adds attribute with Fave instance for each favorited object in `objects` list (iterable with django models)  
213
256
    
214
    if len(bits) != 9:
215
        raise template.TemplateSyntaxError("'%s' tag takes 8 arguments" % bits[0])
216
    
217
    keyword_positions = {2:'by', 4:'of', 5:'type', 7:'as'}
218
    for pos in keyword_positions:
219
        value = keyword_positions[pos]
220
        if bits[pos] != value:
221
            raise template.TemplateSyntaxError("argument #%d to '%s' tag must be '%s'" % (pos, bits[0], value))
222
            
223
    return GetFavoritedNode(bits[1], bits[3], bits[6], bits[8])
257
    Syntax::
258
259
        {% inject_faves_to [objects] by [user] of type [fave-type-slug] as [attribute_name] %}
260
261
    Example::
262
263
        {% inject_faves_to page.object_list by request.user of type favorites as fave %}
264
        
265
        {% for object in page.object_list %}
266
            {{ object }}
267
            {% if object.fave %}
268
                favorited 
269
            {% endif %}
270
        {% endfor %}
271
        
272
    """
273
    bits = token.contents.split()    
274
    validate_template_tag_params(bits, 8, {2:'by', 4:'of', 5:'type', 7:'as'})
275
                
276
    return InjectFavesToNode(bits[1], bits[3], bits[6], bits[8])
224
277
225
278
226
279
@@ -255,16 +308,6 @@ def get_fave(parser, token):
255
308
256
309
    """
257
310
    bits = token.contents.split()
258
    if len(bits) != 10:
259
        raise template.TemplateSyntaxError("'%s' tag takes nine arguments" % bits[0])
260
    if bits[1] != 'by':
261
        raise template.TemplateSyntaxError("first argument to '%s' tag must be 'by'" % bits[0])
262
    if bits[3] != 'on':
263
        raise template.TemplateSyntaxError("third argument to '%s' tag must be 'on'" % bits[0])
264
    if bits[5] != 'of':
265
        raise template.TemplateSyntaxError("fifth argument to '%s' tag must be 'of'" % bits[0])
266
    if bits[6] != 'type':
267
        raise template.TemplateSyntaxError("sixth argument to '%s' tag must be 'type'" % bits[0])
268
    if bits[8] != 'as':
269
        raise template.TemplateSyntaxError("eighth argument to '%s' tag must be 'as'" % bits[0])
311
    validate_template_tag_params(bits, 9, {1:'by', 3:'on', 5:'of', 6:'type', 8:'as'})
312
    
270
313
    return GetFavoriteNode(bits[2], bits[4], bits[7], bits[9])

Up to file-list setup.py:

@@ -3,7 +3,7 @@ from distutils.core import setup
3
3
4
4
setup(
5
5
      name='django-faves',
6
      version='0.6.1',
6
      version='0.6.2',
7
7
      author='jeffrey.a.croft, Mikhail Korobov',
8
8
      author_email='kmike84@gmail.com',
9
9
      url='http://bitbucket.org/kmike/django-faves/',