1 class MenuItem(object):
4 class InvalidMenuItem(BaseException):
7 def __init__(self, url, title, html_id=None, more_urls=None):
10 self.html_id = html_id
11 self.more_urls = more_urls or set()
16 def is_active(self, request, value):
17 url = request.get_full_path()
18 return url == str(self.url) or url in set(str(url) for url in self.more_urls)
20 def check_active(self, request, value):
22 self.active = self.is_active(request, value)
23 except self.InvalidMenuItem, e:
33 class ObjectMenuItem(MenuItem):
34 """Menu item corresponding to an object.
36 If no url or title is provided, get_absolute_url and __unicode__ are used.
37 You can also provide a reverse lookup dictionary, as in {model: field_name}.
40 obj=None, obj_get=None,
41 url=None, rev_lookups=None, title=None, html_id=None):
42 super(ObjectMenuItem, self).__init__(url=url, title=title, html_id=html_id)
44 self.obj_get = obj_get
45 self.rev_lookups = rev_lookups
49 return self.obj or self.obj_get()
50 except BaseException, e:
51 raise self.InvalidMenuItem(e)
54 return self.title or unicode(self.get_object())
57 return self.url or self.get_object().get_absolute_url()
61 obj = self.get_object()
62 except self.InvalidMenuItem, e:
66 def is_active(self, request, value):
67 if value == self.get_object():
70 for model, manager in self.rev_lookups.items():
71 if (isinstance(value, model) and
72 self.get_object() in getattr(value, manager).all()):
77 class ModelMenuItem(MenuItem):
78 """Menu item corresponding to a model, optionally filtered by some fields."""
80 def __init__(self, model, url, field_lookups=None, title=None, html_id=None):
82 title = unicode(model)
83 super(ModelMenuItem, self).__init__(title=title, url=url, html_id=html_id)
85 self.field_lookups = field_lookups
87 def is_active(self, request, value):
88 if value == self.model and not self.field_lookups:
90 if str(self.url) == request.get_full_path():
92 if isinstance(value, self.model) and self.field_lookups:
94 for field, lookup in self.field_lookups.items():
95 if getattr(value, field) != lookup:
102 return self.title or unicode(self.model)