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)