Login

self-related objects list with links

Author:
kumbry
Posted:
November 20, 2007
Language:
Python
Version:
.96
Score:
0 (after 0 ratings)

The problem was to output self-related objects (like category objects which may be a sub-category in any category and so on) in unordered list with links to certain view (providing some object.id arg). Its somewhat like unordered_list tag but takes plain list of objects and provides links.

For example:

category_list = Category.objects.all()

In your template:

{% related_linked_list category_list view_category %}

This tag, however, have some limits:

  1. Model shoud have self-related "parent" and id that may be passed into view.

  2. In model parent = ForeignKey('self', ...) related_name is "child_set".

But its simple enough that you may easily rewrite it for your own needs. :)

 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
from django.core.urlresolvers import reverse, NoReverseMatch
from django.template import Library, Variable, TemplateSyntaxError, Node

register = Library()

class RelatedNode(Node):
    def __init__(self, object_list, viewname):
        self.object_list = Variable(object_list)
        self.viewname = viewname

    def render(self, context):
        def node(object):
            try:
                reversed = reverse(self.viewname, args=[object.id])
            except NoReverseMatch:
                return '<li>%s</li>' % object

            return '<li><a href="%s">%s</li>' % (reversed, object)

        def recursive(object):
            if object.child_set.all():
                output.append('<ul>')
                for object in object.child_set.all():
                    output.append(node(object))
                    recursive(object)
                output.append('</ul>')

        output = []
        for object in self.object_list.resolve(context):
            if not object.parent:
                output.append(node(object))
                recursive(object)

        return '\n'.join(output)

def related_linked_list(parser, token):
    bits = token.contents.split()
    if len(bits) != 3:
        raise TemplateSyntaxError, "'%s' tag takes exactly 2 arguments" % bits[0]
    return RelatedNode(bits[1], bits[2])

register.tag(related_linked_list)

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 1 week ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 2 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

areich (on December 18, 2011):

How do I call this? In other words, what does the view 'view_category' look like to be callable via this tag? urls.py?

Thanks!

#

areich (on December 18, 2011):

via stackoverflow:

In your url conf:

url(r'^some-category/(\d+)/$', some_category_view, name="my-category-view") For your tag, the view_category == "my-category-view"

...So that ultimately the reverse is calling:

reversed = reverse("my-category-view", args=[object.id])

the view returns an HttpResponse

#

Please login first before commenting.