class Menu(models.Model): __metaclass__ = TransMeta name = models.CharField( verbose_name=_('name'), max_length=200, ) slug = models.SlugField( verbose_name=_('slug'), max_length=200, blank=False, null=False, ) help_text = models.CharField( verbose_name=_('help text'), help_text= _('text for describing the menu target, usually placed as link title attribute' ), max_length=200, blank=True, null=True, ) parent = models.ForeignKey( 'Menu', verbose_name=_('Parent'), blank=True, null=True, related_name='child_set', ) url = models.URLField( verbose_name=_('url'), blank=True, null=True, editable=False, ) status = models.CharField( verbose_name=_('status'), help_text=_('status of the menu element'), choices=(('public', _('public')), ('draft', _('draft'))), default='public', max_length=25, ) visible_by_roles = models.ManyToManyField( Role, related_name='visible_menus', verbose_name=_('visible menus'), blank=True, null=True, help_text=_('The roles that will see this menu')) class Meta: verbose_name = _('menu') verbose_name_plural = _('menus') translate = ( 'name', 'help_text', ) def __unicode__(self): return unicode(self.name) def get_absolute_url(self): if self.url == None: self.update_url() return self.url @permalink def get_admin_absolute_url(self): """ Link to the admin page for editing the object """ section = self.get_section() if section: section_content_type = ContentType.objects.get_for_model(section) return ('merengue.base.views.admin_link', [ section_content_type.id, section.id, 'mainmenu/%s/' % self.id ]) else: menu_content_type = ContentType.objects.get_for_model(self) print menu_content_type.id print self.id return ('merengue.base.views.admin_link', [menu_content_type.id, self.id, '']) @permalink def menu_public_link_without_section(self, ancestors_path): return self._menu_public_link_without_section(ancestors_path) def _menu_public_link_without_section(self, ancestors_path): return ('menu_view', (ancestors_path, self.slug)) def public_link(self): menus_ancestors = [ menu.slug for menu in self.get_ancestors() ][1:] # first is a dummy root menu and we discard it ancestors_path = menus_ancestors and '/%s' % '/'.join( menus_ancestors) or '' section = self.get_section() if section: return section.get_real_instance().menu_public_link( ancestors_path, self) else: return self.menu_public_link_without_section(ancestors_path) def update_url(self, commit=True): try: _menu_sections_cache.reload_if_dirty() self.url = self.public_link() except BaseLink.DoesNotExist: self.url = '' if commit: self.save() return self.url def is_published(self): try: return self.baselink.is_published() except BaseLink.DoesNotExist: return True def _get_section(self): try: return getattr(self, 'main_menu_section') except BaseSection.DoesNotExist: pass if self.parent is not None: return self.parent.get_section() get_section = memoize(_get_section, _menu_sections_cache, 1, convert_args_func=_convert_cache_args) def get_breadcrumbs(self): """ Menu breadcrumbs (not included itself) """ bc = [] for parent in self.get_ancestors()[1:]: url = parent.get_absolute_url() bc.append((url, unicode(parent))) section = self.get_section() if section: bc.insert(0, (section.get_absolute_url(), unicode(section))) return bc def get_ancestors_by_user(self, user=None): from merengue.perms.utils import can_manage_site ancestors = self.get_ancestors().filter( status='public') # uses mptt function if user and not can_manage_site(user): if not user.is_anonymous(): roles = Role.objects.filter(principalrolerelation__user=user) else: roles = Role.objects.filter(slug='anonymous_user') ancestors = ancestors.filter( Q(visible_by_roles__isnull=True) | Q(visible_by_roles__in=roles)) return ancestors def get_descendants_by_user(self, user=None): from merengue.perms.utils import can_manage_site descendants = self.get_descendants().filter( status='public') # uses mptt function if user and not can_manage_site(user): if not user.is_anonymous(): roles = Role.objects.filter(principalrolerelation__user=user) else: roles = Role.objects.filter(slug='anonymous_user') descendants = descendants.filter( Q(visible_by_roles__isnull=True) | Q(visible_by_roles__in=roles)).distinct() return descendants def can_edit(self, user): section = self.get_section() if section: return section.can_edit(user) else: return perms_api.can_manage_site(user)
Gets content related blocks excluding the ones overwritten by blocks within the same content """ from merengue.block.models import RegisteredBlock return RegisteredBlock.objects.actives().placed_in(place).with_content( content).exclude_overrided() def _get_all_blocks_to_display(place=None, content=None, section=None): """ Three block groups are fetched separately in increasing priority: - site blocks (no content) - section related blocks - content related blocks """ all_blocks = get_blocks_to_display(place, content) if section: section_blocks = get_blocks_to_display( place, section).exclude_overrided(content) all_blocks = all_blocks | section_blocks sorted(all_blocks, key=lambda b: b.order) return all_blocks get_all_blocks_to_display = memoize(_get_all_blocks_to_display, _blocks_lookup_cache, 3) def clear_lookup_cache(): global _blocks_lookup_cache _blocks_lookup_cache.clear()
get_owners = getattr(obj, 'get_owners', None) get_participants = getattr(obj, 'get_participants', None) if get_owners and callable(get_owners) and user in obj.get_owners(): role_ids.append(Role.objects.get(slug=OWNER_ROLE_SLUG).id) if get_participants and callable(get_participants) and user in obj.get_participants(): role_ids.append(Role.objects.get(slug=PARTICIPANT_ROLE_SLUG).id) try: obj = obj.get_parent_for_permissions() except AttributeError: obj = None return Role.objects.filter(pk__in=role_ids) get_roles = memoize(_get_roles, _roles_cache, 2) def get_global_roles(principal): """Returns global roles of passed principal (user or group). """ if isinstance(principal, AnonymousUser): return Role.objects.filter(slug=ANONYMOUS_ROLE_SLUG) if isinstance(principal, User): return [prr.role for prr in PrincipalRoleRelation.objects.filter( user=principal, content__isnull=True)] else: return [prr.role for prr in PrincipalRoleRelation.objects.filter( group=principal, content__isnull=True)]
def get_blocks_to_display(place=None, content=None): """ Gets content related blocks excluding the ones overwritten by blocks within the same content """ from merengue.block.models import RegisteredBlock return RegisteredBlock.objects.actives().placed_in(place).with_content(content).exclude_overrided() def _get_all_blocks_to_display(place=None, content=None, section=None): """ Three block groups are fetched separately in increasing priority: - site blocks (no content) - section related blocks - content related blocks """ all_blocks = get_blocks_to_display(place, content) if section: section_blocks = get_blocks_to_display(place, section).exclude_overrided(content) all_blocks = all_blocks | section_blocks sorted(all_blocks, key=lambda b: b.order) return all_blocks get_all_blocks_to_display = memoize(_get_all_blocks_to_display, _blocks_lookup_cache, 3) def clear_lookup_cache(): global _blocks_lookup_cache _blocks_lookup_cache.clear()
class RegisteredItemQuerySet(QuerySet): def all(self): return self.filter(broken=False) def actives(self, ordered=False): """ Retrieves active items for site """ if not ordered: return self.filter(active=True) else: return self.filter(active=True).order_by('order') def inactives(self, ordered=False): """ Retrieves inactive items for site """ if not ordered: return self.exclude(active=True) else: return self.exclude(active=True).order_by('order') def with_brokens(self): return self.filter() def get_items(self): """ Returns registrable items (not registered items) """ for item in self.filter(): yield item.get_registry_item() def get_item(self): """ Returns the registrable item (not registered items) """ return self.get().get_registry_item() def get_by_item(self, item): """ obtain registered item passing by param a RegistrableItem """ return self.get(id=item.reg_item.id) def _by_item_class_func(self, item_class): return self.all().filter( module=item_class.get_module(), class_name=item_class.get_class_name()).order_by('-active') _by_item_class = memoize(_by_item_class_func, _registry_lookup_cache, 2, offset=1, convert_args_func=_convert_cache_args, update_cache_if_empty=False) def get_by_item_class(self, item_class): """ obtain registered items passing by param a RegistrableItem class """ try: return self._by_item_class(item_class)[0] except IndexError: raise self.model.DoesNotExist() def by_item_class(self, item_class): """ obtain registered items passing by param a RegistrableItem class """ return FakeRegisteredItemQuerySet(self._by_item_class(item_class)) def by_name(self, name): """ obtains registered items passing a full dotted name to RegistrableItem class """ bits = name.split('.') module = '.'.join(bits[:-1]) class_name = bits[-1] return self.filter( module=module, class_name=class_name, )
if get_owners and callable(get_owners) and user in obj.get_owners(): role_ids.append(Role.objects.get(slug=OWNER_ROLE_SLUG).id) if get_participants and callable( get_participants) and user in obj.get_participants(): role_ids.append(Role.objects.get(slug=PARTICIPANT_ROLE_SLUG).id) try: obj = obj.get_parent_for_permissions() except AttributeError: obj = None return Role.objects.filter(pk__in=role_ids) get_roles = memoize(_get_roles, _roles_cache, 2) def get_global_roles(principal): """Returns global roles of passed principal (user or group). """ if isinstance(principal, AnonymousUser): return Role.objects.filter(slug=ANONYMOUS_ROLE_SLUG) if isinstance(principal, User): return [ prr.role for prr in PrincipalRoleRelation.objects.filter( user=principal, content__isnull=True) ] else: return [ prr.role for prr in PrincipalRoleRelation.objects.filter(