Example #1
0
    def get_content_models(cls):
        """
        Return all Page subclasses that are admin registered, ordered
        based on the ``ADD_PAGE_ORDER`` setting.
        """
        models = []
        for model in Page.get_content_models():
            try:
                admin_url(model, "add")
            except NoReverseMatch:
                continue
            else:
                setattr(model, "meta_verbose_name", model._meta.verbose_name)
                setattr(model, "add_url", admin_url(model, "add"))
                models.append(model)
        order = [name.lower() for name in settings.ADD_PAGE_ORDER]

        def sort_key(page):
            name = "%s.%s" % (page._meta.app_label, page._meta.object_name)
            unordered = len(order)
            try:
                return (order.index(name.lower()), "")
            except ValueError:
                return (unordered, page.meta_verbose_name)
        return sorted(models, key=sort_key)
Example #2
0
 def changelist_view(self, *args, **kwargs):
     """
     Redirect to the add view if no records exist or the change
     view if the singleton instance exists.
     """
     try:
         singleton = self.model.objects.get()
     except self.model.MultipleObjectsReturned:
         return super(SingletonAdmin, self).changelist_view(*args, **kwargs)
     except self.model.DoesNotExist:
         return redirect(admin_url(self.model, "add"))
     return redirect(admin_url(self.model, "change", singleton.id))
Example #3
0
    def test_contenttyped_admin_redirects(self):
        self.client.login(username=self._username, password=self._password)

        # Unsubclassed objects should not redirect
        page = Page.objects.create(title="Test page")
        response = self.client.get(admin_url(Page, "change", page.pk))
        self.assertEqual(response.status_code, 200)

        # Subclassed objects should redirect to the admin for child class
        richtext = RichTextPage.objects.create(title="Test rich text")
        response = self.client.get(admin_url(Page, "change", richtext.pk))
        richtext_change_url = admin_url(RichTextPage, "change", richtext.pk)
        self.assertRedirects(response, richtext_change_url)
Example #4
0
    def get_content_models(self):
        """ Return all subclasses that are admin registered. """
        models = []

        for model in self.concrete_model.get_content_models():
            try:
                admin_url(model, "add")
            except NoReverseMatch:
                continue
            else:
                setattr(model, "meta_verbose_name", model._meta.verbose_name)
                setattr(model, "add_url", admin_url(model, "add"))
                models.append(model)

        return models
Example #5
0
def models_for_pages(*args):
    """
    Create a select list containing each of the models that subclass the
    ``Page`` model.
    """
    page_models = []
    for model in Page.get_content_models():
        try:
            admin_url(model, "add")
        except NoReverseMatch:
            continue
        else:
            setattr(model, "name", model._meta.verbose_name)
            setattr(model, "add_url", admin_url(model, "add"))
            page_models.append(model)
    return page_models
Example #6
0
 def export_view(self, request, form_id):
     """
     Exports the form entries in either a HTML table or CSV file.
     """
     if request.POST.get("back"):
         change_url = admin_url(Form, "change", form_id)
         return HttpResponseRedirect(change_url)
     form = get_object_or_404(Form, id=form_id)
     export_form = ExportForm(form, request, request.POST or None)
     submitted = export_form.is_valid()
     if submitted:
         if request.POST.get("export"):
             response = HttpResponse(mimetype="text/csv")
             timestamp = slugify(datetime.now().ctime())
             fname = "%s-%s.csv" % (form.slug, timestamp)
             header = "attachment; filename=%s" % fname
             response["Content-Disposition"] = header
             csv = writer(response, delimiter=settings.FORMS_CSV_DELIMITER)
             csv.writerow(export_form.columns())
             for rows in export_form.rows():
                 csv.writerow(rows)
             return response
     template = "admin/forms/export.html"
     context = {"title": _("Export Entries"), "export_form": export_form,
                "submitted": submitted}
     return render_to_response(template, context, RequestContext(request))
Example #7
0
 def changelist_view(self, request, extra_context=None):
     """
     Redirect to the ``Page`` changelist view for ``Page`` subclasses.
     """
     if self.model is not Page:
         return HttpResponseRedirect(admin_url(Page, "changelist"))
     return super(PageAdmin, self).changelist_view(request, extra_context)
Example #8
0
    def get_block_type_queryset(self,db):
        qry = None
        for m in self.get_block_models():
            try:
                admin_url(m, 'add')
            except NoReverseMatch:
                continue

            q = models.Q(app_label=m._meta.app_label) & \
                models.Q(model=m._meta.object_name.lower())

            qry = qry | q if qry else q

        # If qry has not been set, i.e. no blocks extend the block_type, or
        # Blocks do not have an admin, then exclude all content types..
        return ContentType.objects.filter(qry).using(db) if qry else \
                ContentType.objects.exclude(pk__gte=0)
Example #9
0
 def add_view(self, request, **kwargs):
     """
     For the ``Page`` model, redirect to the add view for the 
     ``ContentPage`` model.
     """
     if self.model is Page:
         add_url = admin_url(ContentPage, "add")
         return HttpResponseRedirect(add_url)
     return super(PageAdmin, self).add_view(request, **kwargs)
Example #10
0
 def changelist_view(self, request, **kwargs):
     """
     Redirect to the ``Page`` changelist view for ``Page``
     subclasses.
     """
     if self.model is not Page:
         return HttpResponseRedirect(admin_url(Page, "changelist"))
     kwargs.setdefault("extra_context", {})
     kwargs["extra_context"]["page_models"] = self.get_content_models()
     return super(PageAdmin, self).changelist_view(request, **kwargs)
Example #11
0
 def add_view(self, *args, **kwargs):
     """
     Redirect to the change view if the singleton instance exists.
     """
     try:
         singleton = self.model.objects.get()
     except (self.model.DoesNotExist, self.model.MultipleObjectsReturned):
         return super(SingletonAdmin, self).add_view(*args, **kwargs)
     else:
         change_url = admin_url(self.model, "change", singleton.id)
         return HttpResponseRedirect(change_url)
Example #12
0
    def changelist_view(self, request, extra_context=None):
        """ Redirect to the changelist view for subclasses. """
        if self.model is not self.concrete_model:
            return HttpResponseRedirect(
                admin_url(self.concrete_model, "changelist"))

        extra_context = extra_context or {}
        extra_context["content_models"] = self.get_content_models()

        return super(ContentTypedAdmin, self).changelist_view(
            request, extra_context)
Example #13
0
 def entries_view(self, request, form_id):
     """
     Displays the form entries in a HTML table with option to
     export as CSV file.
     """
     if request.POST.get("back"):
         change_url = admin_url(Form, "change", form_id)
         return HttpResponseRedirect(change_url)
     form = get_object_or_404(Form, id=form_id)
     entries_form = EntriesForm(form, request, request.POST or None)
     delete_entries_perm = "%s.delete_formentry" % FormEntry._meta.app_label
     can_delete_entries = request.user.has_perm(delete_entries_perm)
     submitted = entries_form.is_valid()
     if submitted:
         if request.POST.get("export"):
             response = HttpResponse(content_type="text/csv")
             timestamp = slugify(datetime.now().ctime())
             fname = "%s-%s.csv" % (form.slug, timestamp)
             header = "attachment; filename=%s" % fname
             response["Content-Disposition"] = header
             queue = StringIO()
             delimiter = settings.FORMS_CSV_DELIMITER
             try:
                 csv = writer(queue, delimiter=delimiter)
                 writerow = csv.writerow
             except TypeError:
                 queue = BytesIO()
                 delimiter = bytes(delimiter, encoding="utf-8")
                 csv = writer(queue, delimiter=delimiter)
                 writerow = lambda row: csv.writerow([c.encode("utf-8")
                     if hasattr(c, "encode") else c for c in row])
             writerow(entries_form.columns())
             for row in entries_form.rows(csv=True):
                 writerow(row)
             data = queue.getvalue()
             response.write(data)
             return response
         elif request.POST.get("delete") and can_delete_entries:
             selected = request.POST.getlist("selected")
             if selected:
                 entries = FormEntry.objects.filter(id__in=selected)
                 count = entries.count()
                 if count > 0:
                     entries.delete()
                     message = ungettext("1 entry deleted",
                                         "%(count)s entries deleted", count)
                     info(request, message % {"count": count})
     template = "admin/forms/entries.html"
     context = {"title": _("View Entries"), "entries_form": entries_form,
                "opts": self.model._meta, "original": form,
                "can_delete_entries": can_delete_entries,
                "submitted": submitted}
     return render_to_response(template, context, RequestContext(request))
Example #14
0
 def add_view(self, request, extra_context=None, **kwargs):
     """
     For the ``Page`` model, redirect to the add view for the
     ``RichText`` model.
     """
     if self.model is Page:
         try:
             add_url = admin_url(RichTextPage, "add")
             return HttpResponseRedirect(add_url)
         except NoReverseMatch:
             pass
     return super(PageAdmin, self).add_view(request, **kwargs)
Example #15
0
 def add_view(self, *args, **kwargs):
     """
     Redirect to the change view if the singleton instance exists.
     """
     try:
         singleton = self.model.objects.get()
     except (self.model.DoesNotExist, self.model.MultipleObjectsReturned):
         kwargs.setdefault("extra_context", {})
         kwargs["extra_context"]["singleton"] = True
         response = super(SingletonAdmin, self).add_view(*args, **kwargs)
         return self.handle_save(args[0], response)
     return redirect(admin_url(self.model, "change", singleton.id))
Example #16
0
def models_for_pages(*args):
    """
    Create a select list containing each of the models that subclass the
    ``Page`` model.
    """
    page_models = []
    for model in get_models():
        if model is not Page and issubclass(model, Page):
            setattr(model, "name", model._meta.verbose_name)
            setattr(model, "add_url", admin_url(model, "add"))
            page_models.append(model)
    return page_models
Example #17
0
 def change_view(self, request, object_id, extra_context=None):
     """
     As in Mezzanine's ``Page`` model, check ``product.get_content_model()``
     for a subclass and redirect to its admin change view.
     """
     if self.model is Product:
         product = get_object_or_404(Product, pk=object_id)
         content_model = product.get_content_model()
         if content_model is not None:
             change_url = admin_url(content_model.__class__, "change", content_model.id)
             return HttpResponseRedirect(change_url)
     return super(ProductAdmin, self).change_view(request, object_id, extra_context=extra_context)
Example #18
0
def send_approve_mail(request, user):
    """
    Sends an email to staff in listed in the setting
    ``ACCOUNTS_APPROVAL_EMAILS``, when a new user signs up and the
    ``ACCOUNTS_APPROVAL_REQUIRED`` setting is ``True``.
    """
    settings.use_editable()
    approval_emails = split_addresses(settings.ACCOUNTS_APPROVAL_EMAILS)
    if not approval_emails:
        return
    context = {"request": request, "user": user, "change_url": admin_url(user.__class__, "change", user.id)}
    subject = subject_template("email/account_approve_subject.txt", context)
    send_mail_template(subject, "email/account_approve", settings.DEFAULT_FROM_EMAIL, approval_emails, context=context)
Example #19
0
def create_page(request):
    models = request.GET['module']
    pageclass = request.GET['classname']
    parent = request.GET['parent']

    parent = Page.objects.get(slug=parent).get_content_model()
    models = importlib.import_module(models)
    pageclass = getattr(models, pageclass)

    title = request.GET.get('title', "new " + pageclass._meta.object_name)
    # page = pageclass.objects.create(title=title, parent=parent)
    return HttpResponseRedirect(
        admin_url(pageclass, 'add') + "?parent={pk}&next={next}".format(pk=parent.pk, next=parent.get_absolute_url()))
Example #20
0
 def change_view(self, request, object_id, extra_context=None):
     """
     For the ``Page`` model, check ``page.get_content_model()`` for a
     subclass and redirect to its admin change view.
     """
     if self.model is Page:
         page = get_object_or_404(Page, pk=object_id)
         content_model = page.get_content_model()
         if content_model is not None:
             change_url = admin_url(content_model.__class__, "change",
                                     content_model.id)
             return HttpResponseRedirect(change_url)
     return super(PageAdmin, self).change_view(request, object_id,
                                                 extra_context=None)
Example #21
0
def models_for_products(*args):
    """
    Create a select list containing each of the models that subclass the
    ``Product`` model, plus the ``Product`` model itself.
    """
    product_models = []
    for model in Product.get_content_models():
        try:
            admin_add_url = admin_url(model, "add")
        except NoReverseMatch:
            continue
        else:
            setattr(model, "name", model._meta.verbose_name)
            setattr(model, "add_url", admin_add_url)
            product_models.append(model)
    return product_models
Example #22
0
    def change_view(self, request, object_id, **kwargs):
        """
        For the concrete model, check ``get_content_model()``
        for a subclass and redirect to its admin change view.
        """
        instance = get_object_or_404(self.concrete_model, pk=object_id)
        content_model = instance.get_content_model()

        self.check_permission(request, content_model, "change")

        if content_model.__class__ != self.model:
            change_url = admin_url(content_model.__class__, "change",
                                   content_model.id)
            return HttpResponseRedirect(change_url)

        return super(ContentTypedAdmin, self).change_view(
            request, object_id, **kwargs)
Example #23
0
 def change_view(self, request, object_id, **kwargs):
     """
     For the ``Page`` model, check ``page.get_content_model()``
     for a subclass and redirect to its admin change view.
     Also enforce custom change permissions for the page instance.
     """
     page = get_object_or_404(Page, pk=object_id)
     content_model = page.get_content_model()
     self._check_permission(request, content_model, "change")
     if self.model is Page:
         if content_model is not None:
             change_url = admin_url(content_model.__class__, "change", content_model.id)
             return HttpResponseRedirect(change_url)
     kwargs.setdefault("extra_context", {})
     kwargs["extra_context"].update(
         {"hide_delete_link": not content_model.can_delete(request), "hide_slug_field": content_model.overridden()}
     )
     return super(PageAdmin, self).change_view(request, object_id, **kwargs)
Example #24
0
 def change_view(self, request, object_id, extra_context=None):
     """
     For the ``Page`` model, check ``page.get_content_model()``
     for a subclass and redirect to its admin change view.
     Also enforce custom change permissions for the page instance.
     """
     page = get_object_or_404(Page, pk=object_id)
     content_model = page.get_content_model()
     self._check_permission(request, content_model, "change")
     if self.model is Page:
         if content_model is not None:
             change_url = admin_url(content_model.__class__, "change",
                                    content_model.id)
             return HttpResponseRedirect(change_url)
     extra_context = extra_context or {}
     extra_context["hide_delete_link"] = not page.can_delete(request)
     extra_context["hide_slug_field"] = not page.overridden()
     return super(PageAdmin, self).change_view(request, object_id,
                                               extra_context)
Example #25
0
 def export_view(self, request, form_id):
     """
     Output a CSV file to the browser containing the entries for the form.
     """
     if request.POST.get("back"):
         change_url = admin_url(Form, "change", form_id)
         return HttpResponseRedirect(change_url)
     form = get_object_or_404(Form, id=form_id)
     export_form = ExportForm(form, request, request.POST or None)
     if export_form.is_valid():
         response = HttpResponse(mimetype="text/csv")
         fname = "%s-%s.csv" % (form.slug, slugify(datetime.now().ctime()))
         response["Content-Disposition"] = "attachment; filename=%s" % fname
         csv = writer(response)
         csv.writerow(export_form.columns())
         for rows in export_form.rows():
             csv.writerow(rows)
         return response
     template = "admin/forms/export.html"
     context = {"title": _("Export Entries"), "export_form": export_form}
     return render_to_response(template, context, RequestContext(request))
Example #26
0
def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``.
    Returns a list of lists of models grouped and ordered according to
    ``mezzanine.conf.ADMIN_MENU_ORDER``. Called from the
    ``admin_dropdown_menu`` template tag as well as the ``app_list``
    dashboard widget.
    """
    app_dict = {}

    # Model or view --> (group index, group title, item index, item title).
    menu_order = {}
    for (group_index, group) in enumerate(settings.ADMIN_MENU_ORDER):
        group_title, items = group
        group_title = group_title.title()
        for (item_index, item) in enumerate(items):
            if isinstance(item, (tuple, list)):
                item_title, item = item
            else:
                item_title = None
            menu_order[item] = (group_index, group_title,
                                item_index, item_title)

    # Add all registered models, using group and title from menu order.
    for (model, model_admin) in admin.site._registry.items():
        opts = model._meta
        in_menu = not hasattr(model_admin, "in_menu") or model_admin.in_menu()
        if in_menu and request.user.has_module_perms(opts.app_label):
            perms = model_admin.get_model_perms(request)
            admin_url_name = ""
            if perms["change"]:
                admin_url_name = "changelist"
                change_url = admin_url(model, admin_url_name)
            else:
                change_url = None
            if perms["add"]:
                admin_url_name = "add"
                add_url = admin_url(model, admin_url_name)
            else:
                add_url = None
            if admin_url_name:
                model_label = "%s.%s" % (opts.app_label, opts.object_name)
                try:
                    app_index, app_title, model_index, model_title = \
                        menu_order[model_label]
                except KeyError:
                    app_index = None
                    app_title = opts.app_label.title()
                    model_index = None
                    model_title = None
                else:
                    del menu_order[model_label]

                if not model_title:
                    model_title = capfirst(model._meta.verbose_name_plural)

                if app_title not in app_dict:
                    app_dict[app_title] = {
                        "index": app_index,
                        "name": app_title,
                        "models": [],
                    }
                app_dict[app_title]["models"].append({
                    "index": model_index,
                    "perms": model_admin.get_model_perms(request),
                    "name": model_title,
                    "admin_url": change_url,
                    "add_url": add_url
                })

    # Menu may also contain view or url pattern names given as (title, name).
    for (item_url, item) in menu_order.iteritems():
        app_index, app_title, item_index, item_title = item
        try:
            item_url = reverse(item_url)
        except NoReverseMatch:
            continue
        if app_title not in app_dict:
            app_dict[app_title] = {
                "index": app_index,
                "name": app_title,
                "models": [],
            }
        app_dict[app_title]["models"].append({
            "index": item_index,
            "perms": {"custom": True},
            "name": item_title,
            "admin_url": item_url,
        })

    app_list = app_dict.values()
    sort = lambda x: x["name"] if x["index"] is None else x["index"]
    for app in app_list:
        app["models"].sort(key=sort)
    app_list.sort(key=sort)
    return app_list
Example #27
0
 def changelist_redirect(self):
     changelist_url = admin_url(Setting, "changelist")
     return HttpResponseRedirect(changelist_url)
Example #28
0
 def get_admin_url(self):
     return admin_url(self, "change", self.id)
Example #29
0
def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``. Returns a
    list of lists of models grouped and ordered according to
    ``mezzanine.conf.ADMIN_MENU_ORDER``. Called from the
    ``admin_dropdown_menu`` template tag as well as the ``app_list``
    dashboard widget.
    """
    app_dict = {}
    menu_order = [(x[0], list(x[1])) for x in settings.ADMIN_MENU_ORDER]
    found_items = set()
    for (model, model_admin) in admin.site._registry.items():
        opts = model._meta
        in_menu = not hasattr(model_admin, "in_menu") or model_admin.in_menu()
        if in_menu and request.user.has_module_perms(opts.app_label):
            perms = model_admin.get_model_perms(request)
            admin_url_name = ""
            if perms["change"]:
                admin_url_name = "changelist"
            elif perms["add"]:
                admin_url_name = "add"
            if admin_url_name:
                model_label = "%s.%s" % (opts.app_label, opts.object_name)
                for (name, items) in menu_order:
                    try:
                        index = list(items).index(model_label)
                    except ValueError:
                        pass
                    else:
                        found_items.add(model_label)
                        app_title = name
                        break
                else:
                    index = None
                    app_title = opts.app_label
                model_dict = {
                    "index": index,
                    "perms": model_admin.get_model_perms(request),
                    "name": capfirst(model._meta.verbose_name_plural),
                    "admin_url": admin_url(model, admin_url_name),
                }
                app_title = app_title.title()
                if app_title in app_dict:
                    app_dict[app_title]["models"].append(model_dict)
                else:
                    try:
                        titles = [x[0] for x in settings.ADMIN_MENU_ORDER]
                        index = titles.index(app_title)
                    except ValueError:
                        index = None
                    app_dict[app_title] = {
                        "index": index,
                        "name": app_title,
                        "models": [model_dict],
                    }

    for (i, (name, items)) in enumerate(menu_order):
        name = unicode(name)
        for unfound_item in set(items) - found_items:
            if isinstance(unfound_item, (list, tuple)):
                item_name, item_url = unfound_item[0], try_url(unfound_item[1])
                if item_url:
                    if name not in app_dict:
                        app_dict[name] = {
                            "index": i,
                            "name": name,
                            "models": [],
                        }
                    app_dict[name]["models"].append({
                        "index": items.index(unfound_item),
                        "perms": {"custom": True},
                        "name": item_name,
                        "admin_url": item_url,
                    })

    app_list = app_dict.values()
    sort = lambda x: x["name"] if x["index"] is None else x["index"]
    for app in app_list:
        app["models"].sort(key=sort)
    app_list.sort(key=sort)
    return app_list
Example #30
0
 def get_admin_url(self):
     return admin_url(self, "change", self.id)
Example #31
0
def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``.
    Returns a list of lists of models grouped and ordered according to
    ``mezzanine.conf.ADMIN_MENU_ORDER``. Called from the
    ``admin_dropdown_menu`` template tag as well as the ``app_list``
    dashboard widget.
    """
    app_dict = {}

    # Model or view --> (group index, group title, item index, item title).
    menu_order = {}
    for (group_index, group) in enumerate(settings.ADMIN_MENU_ORDER):
        group_title, items = group
        group_title = group_title.title()
        for (item_index, item) in enumerate(items):
            if isinstance(item, (tuple, list)):
                item_title, item = item
            else:
                item_title = None
            menu_order[item] = (group_index, group_title, item_index, item_title)

    # Add all registered models, using group and title from menu order.
    for (model, model_admin) in admin.site._registry.items():
        opts = model._meta
        in_menu = not hasattr(model_admin, "in_menu") or model_admin.in_menu()
        if in_menu and request.user.has_module_perms(opts.app_label):
            perms = model_admin.get_model_perms(request)
            admin_url_name = ""
            if perms["change"]:
                admin_url_name = "changelist"
                change_url = admin_url(model, admin_url_name)
            else:
                change_url = None
            if perms["add"]:
                admin_url_name = "add"
                add_url = admin_url(model, admin_url_name)
            else:
                add_url = None
            if admin_url_name:
                model_label = "%s.%s" % (opts.app_label, opts.object_name)
                try:
                    app_index, app_title, model_index, model_title = menu_order[model_label]
                except KeyError:
                    app_index = None
                    app_title = opts.app_label.title()
                    model_index = None
                    model_title = None
                else:
                    del menu_order[model_label]

                if not model_title:
                    model_title = capfirst(model._meta.verbose_name_plural)

                if app_title not in app_dict:
                    app_dict[app_title] = {"index": app_index, "name": app_title, "models": []}
                app_dict[app_title]["models"].append(
                    {
                        "index": model_index,
                        "perms": model_admin.get_model_perms(request),
                        "name": model_title,
                        "admin_url": change_url,
                        "add_url": add_url,
                    }
                )

    # Menu may also contain view or url pattern names given as (title, name).
    for (item_url, item) in menu_order.iteritems():
        app_index, app_title, item_index, item_title = item
        try:
            item_url = reverse(item_url)
        except NoReverseMatch:
            continue
        if app_title not in app_dict:
            app_dict[app_title] = {"index": app_index, "name": app_title, "models": []}
        app_dict[app_title]["models"].append(
            {"index": item_index, "perms": {"custom": True}, "name": item_title, "admin_url": item_url}
        )

    app_list = app_dict.values()
    sort = lambda x: x["name"] if x["index"] is None else x["index"]
    for app in app_list:
        app["models"].sort(key=sort)
    app_list.sort(key=sort)
    return app_list
Example #32
0
def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``.
    Returns a list of lists of models grouped and ordered according to
    ``mezzanine.conf.ADMIN_MENU_ORDER``. Called from the
    ``admin_dropdown_menu`` template tag as well as the ``app_list``
    dashboard widget.
    """
    app_dict = {}

    # Model or view --> (group index, group title, item index, item title).
    menu_order = {}
    for (group_index, group) in enumerate(settings.ADMIN_MENU_ORDER):
        group_title, items = group
        for (item_index, item) in enumerate(items):
            if isinstance(item, (tuple, list)):
                item_title, item = item
            else:
                item_title = None
            menu_order[item] = (group_index, group_title, item_index, item_title)

    # Add all registered models, using group and title from menu order.
    for (model, model_admin) in admin.site._registry.items():
        opts = model._meta
        in_menu = not hasattr(model_admin, "in_menu") or model_admin.in_menu()
        if hasattr(model_admin, "in_menu"):
            import warnings

            warnings.warn(
                "ModelAdmin.in_menu() has been replaced with "
                "ModelAdmin.has_module_permission(request). See "
                "https://docs.djangoproject.com/en/stable/ref/contrib/admin/"
                "#django.contrib.admin.ModelAdmin.has_module_permission.",
                DeprecationWarning,
            )
        in_menu = in_menu and model_admin.has_module_permission(request)
        if in_menu and request.user.has_module_perms(opts.app_label):
            admin_url_name = ""
            if model_admin.has_change_permission(request):
                admin_url_name = "changelist"
                change_url = admin_url(model, admin_url_name)
            else:
                change_url = None
            if model_admin.has_add_permission(request):
                admin_url_name = "add"
                add_url = admin_url(model, admin_url_name)
            else:
                add_url = None
            if admin_url_name:
                model_label = "%s.%s" % (opts.app_label, opts.object_name)
                try:
                    app_index, app_title, model_index, model_title = menu_order[model_label]
                except KeyError:
                    app_index = None
                    try:
                        app_title = opts.app_config.verbose_name.title()
                    except AttributeError:
                        # Third party admin classes doing weird things.
                        # See GH #1628
                        app_title = ""
                    model_index = None
                    model_title = None
                else:
                    del menu_order[model_label]

                if not model_title:
                    model_title = capfirst(model._meta.verbose_name_plural)

                if app_title not in app_dict:
                    app_dict[app_title] = {"index": app_index, "name": app_title, "models": []}
                app_dict[app_title]["models"].append(
                    {
                        "index": model_index,
                        "perms": model_admin.get_model_perms(request),
                        "name": model_title,
                        "object_name": opts.object_name,
                        "admin_url": change_url,
                        "add_url": add_url,
                    }
                )

    # Menu may also contain view or url pattern names given as (title, name).
    for (item_url, item) in menu_order.items():
        app_index, app_title, item_index, item_title = item
        try:
            item_url = reverse(item_url)
        except NoReverseMatch:
            continue
        if app_title not in app_dict:
            app_dict[app_title] = {"index": app_index, "name": app_title, "models": []}
        app_dict[app_title]["models"].append(
            {"index": item_index, "perms": {"custom": True}, "name": item_title, "admin_url": item_url}
        )

    app_list = list(app_dict.values())
    sort = lambda x: (x["index"] if x["index"] is not None else 999, x["name"])
    for app in app_list:
        app["models"].sort(key=sort)
    app_list.sort(key=sort)
    return app_list
Example #33
0
def page_menu(context, token):
    """
    Return a list of child pages for the given parent, storing all
    pages in a dict in the context when first called using parents as keys
    for retrieval on subsequent recursive calls from the menu template.
    """
    # First arg could be the menu template file name, or the parent page.
    # Also allow for both to be used.
    template_name = None
    parent_page = None
    parts = token.split_contents()[1:]
    for part in parts:
        part = Variable(part).resolve(context)
        if isinstance(part, unicode):
            template_name = part
        elif isinstance(part, Page):
            parent_page = part
    if template_name is None:
        try:
            template_name = context["menu_template_name"]
        except KeyError:
            error = "No template found for page_menu in: %s" % parts
            raise TemplateSyntaxError(error)
    context["menu_template_name"] = template_name
    if "menu_pages" not in context:
        try:
            user = context["request"].user
            slug = context["request"].path
        except KeyError:
            user = None
            slug = ""
        num_children = lambda id: lambda: len(context["menu_pages"][id])
        has_children = lambda id: lambda: num_children(id)() > 0
        published = Page.objects.published(for_user=user)
        if slug == admin_url(Page, "changelist"):
            related = [m.__name__.lower() for m in Page.get_content_models()]
            published = published.select_related(*related)
        else:
            published = published.select_related(depth=2)
        # Store the current page being viewed in the context. Used
        # for comparisons in page.set_menu_helpers.
        if "page" not in context:
            try:
                context["_current_page"] = published.get(slug=slug)
            except Page.DoesNotExist:
                context["_current_page"] = None
        elif slug:
            context["_current_page"] = context["page"]
        # Some homepage related context flags. on_home is just a helper
        # indicated we're on the homepage. has_home indicates an actual
        # page object exists for the homepage, which can be used to
        # determine whether or not to show a hard-coded homepage link
        # in the page menu.
        home = home_slug()
        context["on_home"] = slug == home
        context["has_home"] = False
        # Maintain a dict of page IDs -> parent IDs for fast
        # lookup in setting page.is_current_or_ascendant in
        # page.set_menu_helpers.
        context["_parent_page_ids"] = {}
        pages = defaultdict(list)
        for page in published.order_by("_order"):
            page.set_helpers(context)
            context["_parent_page_ids"][page.id] = page.parent_id
            setattr(page, "num_children", num_children(page.id))
            setattr(page, "has_children", has_children(page.id))
            pages[page.parent_id].append(page)
            if page.slug == home:
                context["has_home"] = True
        context["menu_pages"] = pages
    # ``branch_level`` must be stored against each page so that the
    # calculation of it is correctly applied. This looks weird but if we do
    # the ``branch_level`` as a separate arg to the template tag with the
    # addition performed on it, the addition occurs each time the template
    # tag is called rather than once per level.
    context["branch_level"] = 0
    parent_page_id = None
    if parent_page is not None:
        context["branch_level"] = getattr(parent_page, "branch_level", 0) + 1
        parent_page_id = parent_page.id

    # Build the ``page_branch`` template variable, which is the list of
    # pages for the current parent. Here we also assign the attributes
    # to the page object that determines whether it belongs in the
    # current menu template being rendered.
    context["page_branch"] = context["menu_pages"].get(parent_page_id, [])
    context["page_branch_in_menu"] = False
    for page in context["page_branch"]:
        page.in_menu = page.in_menu_template(template_name)
        page.num_children_in_menu = 0
        if page.in_menu:
            context["page_branch_in_menu"] = True
        for child in context["menu_pages"].get(page.id, []):
            if child.in_menu_template(template_name):
                page.num_children_in_menu += 1
        page.has_children_in_menu = page.num_children_in_menu > 0
        page.branch_level = context["branch_level"]
        page.parent = parent_page

        # Prior to pages having the ``in_menus`` field, pages had two
        # boolean fields ``in_navigation`` and ``in_footer`` for
        # controlling menu inclusion. Attributes and variables
        # simulating these are maintained here for backwards
        # compatibility in templates, but will be removed eventually.
        page.in_navigation = page.in_menu
        page.in_footer = not (not page.in_menu and "footer" in template_name)
        if page.in_navigation:
            context["page_branch_in_navigation"] = True
        if page.in_footer:
            context["page_branch_in_footer"] = True

    t = get_template(template_name)
    return t.render(context)
Example #34
0
 def changelist_redirect(self):
     changelist_url = admin_url(Setting, "changelist")
     return HttpResponseRedirect(changelist_url)
Example #35
0
def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``.
    Returns a list of lists of models grouped and ordered according to
    ``mezzanine.conf.ADMIN_MENU_ORDER``. Called from the
    ``admin_dropdown_menu`` template tag as well as the ``app_list``
    dashboard widget.
    """
    app_dict = {}

    # Model or view --> (group index, group title, item index, item title).
    menu_order = {}
    for (group_index, group) in enumerate(settings.ADMIN_MENU_ORDER):
        group_title, items = group
        for (item_index, item) in enumerate(items):
            if isinstance(item, (tuple, list)):
                item_title, item = item
            else:
                item_title = None
            menu_order[item] = (group_index, group_title, item_index,
                                item_title)

    # Add all registered models, using group and title from menu order.
    for (model, model_admin) in admin.site._registry.items():
        opts = model._meta
        in_menu = not hasattr(model_admin, "in_menu") or model_admin.in_menu()
        if hasattr(model_admin, "in_menu"):
            import warnings
            warnings.warn(
                'ModelAdmin.in_menu() has been replaced with '
                'ModelAdmin.has_module_permission(request). See '
                'https://docs.djangoproject.com/en/stable/ref/contrib/admin/'
                '#django.contrib.admin.ModelAdmin.has_module_permission.',
                DeprecationWarning)
        in_menu = in_menu and model_admin.has_module_permission(request)
        if in_menu and request.user.has_module_perms(opts.app_label):
            admin_url_name = ""
            if model_admin.has_change_permission(request):
                admin_url_name = "changelist"
                change_url = admin_url(model, admin_url_name)
            else:
                change_url = None
            if model_admin.has_add_permission(request):
                admin_url_name = "add"
                add_url = admin_url(model, admin_url_name)
            else:
                add_url = None
            if admin_url_name:
                model_label = "%s.%s" % (opts.app_label, opts.object_name)
                try:
                    app_index, app_title, model_index, model_title = \
                        menu_order[model_label]
                except KeyError:
                    app_index = None
                    try:
                        app_title = opts.app_config.verbose_name.title()
                    except AttributeError:
                        # Third party admin classes doing weird things.
                        # See GH #1628
                        app_title = ""
                    model_index = None
                    model_title = None
                else:
                    del menu_order[model_label]

                if not model_title:
                    model_title = capfirst(model._meta.verbose_name_plural)

                if app_title not in app_dict:
                    app_dict[app_title] = {
                        "index": app_index,
                        "name": app_title,
                        "models": [],
                    }
                app_dict[app_title]["models"].append({
                    "index":
                    model_index,
                    "perms":
                    model_admin.get_model_perms(request),
                    "name":
                    model_title,
                    "object_name":
                    opts.object_name,
                    "admin_url":
                    change_url,
                    "add_url":
                    add_url
                })

    # Menu may also contain view or url pattern names given as (title, name).
    for (item_url, item) in menu_order.items():
        app_index, app_title, item_index, item_title = item
        try:
            item_url = reverse(item_url)
        except NoReverseMatch:
            continue
        if app_title not in app_dict:
            app_dict[app_title] = {
                "index": app_index,
                "name": app_title,
                "models": [],
            }
        app_dict[app_title]["models"].append({
            "index": item_index,
            "perms": {
                "custom": True
            },
            "name": item_title,
            "admin_url": item_url,
        })

    app_list = list(app_dict.values())
    sort = lambda x: (x["index"] if x["index"] is not None else 999, x["name"])
    for app in app_list:
        app["models"].sort(key=sort)
    app_list.sort(key=sort)
    return app_list
Example #36
0
def page_menu(context, token):
    """
    Return a list of child pages for the given parent, storing all
    pages in a dict in the context when first called using parents as keys
    for retrieval on subsequent recursive calls from the menu template.
    """
    # First arg could be the menu template file name, or the parent page.
    # Also allow for both to be used.
    template_name = None
    parent_page = None
    parts = token.split_contents()[1:]
    for part in parts:
        part = Variable(part).resolve(context)
        if isinstance(part, unicode):
            template_name = part
        elif isinstance(part, Page):
            parent_page = part
    if template_name is None:
        try:
            template_name = context["menu_template_name"]
        except KeyError:
            error = "No template found for page_menu in: %s" % parts
            raise TemplateSyntaxError(error)
    context["menu_template_name"] = template_name
    if "menu_pages" not in context:
        try:
            user = context["request"].user
            slug = context["request"].path
        except KeyError:
            user = None
            slug = ""
        num_children = lambda id: lambda: len(context["menu_pages"][id])
        has_children = lambda id: lambda: num_children(id)() > 0
        published = Page.objects.published(for_user=user)
        if slug == admin_url(Page, "changelist"):
            related = [m.__name__.lower() for m in Page.get_content_models()]
            published = published.select_related(*related)
        else:
            published = published.select_related(depth=2)
        # Store the current page being viewed in the context. Used
        # for comparisons in page.set_menu_helpers.
        if "page" not in context:
            try:
                context["_current_page"] = published.get(slug=slug)
            except Page.DoesNotExist:
                context["_current_page"] = None
        elif slug:
            context["_current_page"] = context["page"]
        # Maintain a dict of page IDs -> parent IDs for fast
        # lookup in setting page.is_current_or_ascendant in
        # page.set_menu_helpers.
        context["_parent_page_ids"] = {}
        pages = defaultdict(list)
        for page in published.order_by("_order"):
            page.set_helpers(context)
            context["_parent_page_ids"][page.id] = page.parent_id
            setattr(page, "num_children", num_children(page.id))
            setattr(page, "has_children", has_children(page.id))
            pages[page.parent_id].append(page)
        context["menu_pages"] = pages
        context["on_home"] = slug == reverse("home")
    # ``branch_level`` must be stored against each page so that the
    # calculation of it is correctly applied. This looks weird but if we do
    # the ``branch_level`` as a separate arg to the template tag with the
    # addition performed on it, the addition occurs each time the template
    # tag is called rather than once per level.
    context["branch_level"] = 0
    parent_page_id = None
    if parent_page is not None:
        context["branch_level"] = getattr(parent_page, "branch_level", 0) + 1
        parent_page_id = parent_page.id

    context["page_branch"] = context["menu_pages"].get(parent_page_id, [])
    context["page_branch_in_menu"] = False
    for page in context["page_branch"]:
        # footer/nav for backward compatibility. Also check that in_menus
        # has a value, as it may not have been populated correctly
        # if migrations weren't run when it was added.
        page.in_footer = page.in_navigation = page.in_menu = True
        if page.in_menus is not None:
            for i, l, t in settings.PAGE_MENU_TEMPLATES:
                if not unicode(i) in page.in_menus and t == template_name:
                    page.in_navigation = page.in_menu = False
                    if "footer" in template_name:
                        page.in_footer = False
                    break
        if page.in_menu:
            context["page_branch_in_menu"] = True
    # Backwards compatibility
    context['page_branch_in_navigation'] = context["page_branch_in_menu"]
    context['page_branch_in_footer'] = (context["page_branch_in_menu"] and
                                    template_name == "pages/menu/footer.html")

    for i, page in enumerate(context["page_branch"]):
        context["page_branch"][i].branch_level = context["branch_level"]
        context["page_branch"][i].parent = parent_page
    t = get_template(template_name)
    return t.render(context)
Example #37
0
def admin_app_list(request):
    """
    Adopted from ``django.contrib.admin.sites.AdminSite.index``. Returns a
    list of lists of models grouped and ordered according to
    ``mezzanine.conf.ADMIN_MENU_ORDER``. Called from the
    ``admin_dropdown_menu`` template tag as well as the ``app_list``
    dashboard widget.
    """
    app_dict = {}
    menu_order = [(x[0], list(x[1])) for x in settings.ADMIN_MENU_ORDER]
    found_items = set()
    for (model, model_admin) in admin.site._registry.items():
        opts = model._meta
        in_menu = not hasattr(model_admin, "in_menu") or model_admin.in_menu()
        if in_menu and request.user.has_module_perms(opts.app_label):
            perms = model_admin.get_model_perms(request)
            admin_url_name = ""
            if perms["change"]:
                admin_url_name = "changelist"
            elif perms["add"]:
                admin_url_name = "add"
            if admin_url_name:
                model_label = "%s.%s" % (opts.app_label, opts.object_name)
                for (name, items) in menu_order:
                    try:
                        index = list(items).index(model_label)
                    except ValueError:
                        pass
                    else:
                        found_items.add(model_label)
                        app_title = name
                        break
                else:
                    index = None
                    app_title = opts.app_label
                model_dict = {
                    "index": index,
                    "perms": model_admin.get_model_perms(request),
                    "name": capfirst(model._meta.verbose_name_plural),
                    "admin_url": admin_url(model, admin_url_name),
                }
                app_title = app_title.title()
                if app_title in app_dict:
                    app_dict[app_title]["models"].append(model_dict)
                else:
                    try:
                        titles = [x[0] for x in settings.ADMIN_MENU_ORDER]
                        index = titles.index(app_title)
                    except ValueError:
                        index = None
                    app_dict[app_title] = {
                        "index": index,
                        "name": app_title,
                        "models": [model_dict],
                    }

    for (i, (name, items)) in enumerate(menu_order):
        name = unicode(name)
        for unfound_item in set(items) - found_items:
            if isinstance(unfound_item, (list, tuple)):
                item_name, item_url = unfound_item[0], try_url(unfound_item[1])
                if item_url:
                    if name not in app_dict:
                        app_dict[name] = {
                            "index": i,
                            "name": name,
                            "models": [],
                        }
                    app_dict[name]["models"].append({
                        "index":
                        items.index(unfound_item),
                        "perms": {
                            "custom": True
                        },
                        "name":
                        item_name,
                        "admin_url":
                        item_url,
                    })

    app_list = app_dict.values()
    sort = lambda x: x["name"] if x["index"] is None else x["index"]
    for app in app_list:
        app["models"].sort(key=sort)
    app_list.sort(key=sort)
    return app_list