【问题标题】:Django, apps list template tag in admin base.htmlDjango,admin base.html 中的应用程序列表模板标签
【发布时间】:2014-09-13 18:19:10
【问题描述】:

所以我正在尝试为 Django Admin 创建一个模板。我无法显示的是安装了所有应用程序的列表(将成为菜单)。与 django 管理模板的 index.html 几乎完全相同。我在this link 上找到了一篇关于如何重新创建此列表的文章。我不是 100% 认为这段代码可以与 Django 1.7 rc1 一起使用(也尝试过 1.6 但仍然没有),但我想我可以试一试。

主要问题是我无法管理如何使用菜单显示模板标签。我过去创建了自定义模板标签,所以我仔细检查了以下内容:

  • init模板标签文件夹中的.py
  • 应用和模板标签都在设置中注册

我得到的错误是 'custom_menu' 不是有效的标签库:ImportError raise loading loading djangobackend.apps.djangonicebackend.templatetags.custom_menu: cannot import name validate.....

您可以在下面找到我的代码。

custom_menu.py(在模板标签目录内)

from django.utils.text import capfirst
from django.db.models import get_models
from django.utils.safestring import mark_safe
from django.contrib.admin import ModelAdmin
from django.contrib.admin.validation import validate
from django.template.loader import get_template
from django import template

register = template.Library()

IGNORE_MODELS = (
    "sites",
    "sessions",
    "admin",
    "contenttypes",
)


def custom_app_list(request):
    # Get all models and add them to the context apps variable.
    user = request.user
    app_dict = {}
    admin_class = ModelAdmin
    for model in get_models():
        validate(admin_class, model)
        model_admin = admin_class(model, None)
        app_label = model._meta.app_label
        if app_label in IGNORE_MODELS:
            continue
        has_module_perms = user.has_module_perms(app_label)
        if has_module_perms:
            perms = model_admin.get_model_perms(request)
            # Check whether user has any perm for this module.
            # If so, add the module to the model_list.
            if True in perms.values():
                model_dict = {
                    'name': capfirst(model._meta.verbose_name_plural),
                    'admin_url': mark_safe('%s/%s/' % (app_label, model.__name__.lower())),
                }
                if app_label in app_dict:
                    app_dict[app_label]['models'].append(model_dict)
                else:
                    app_dict[app_label] = {
                        'name': app_label.title(),
                        'app_url': app_label + '/',
                        'has_module_perms': has_module_perms,
                        'models': [model_dict],
                    }
    app_list = app_dict.values()
    app_list.sort(key=lambda x: x['name'])
    for app in app_list:
        app['models'].sort(key=lambda x: x['name'])
    return {'apps': app_list}


t = get_template('templatetags/custom_menu.html')
register.inclusion_tag(t)(custom_app_list)

custom_menu.html (app/templates/templatetags/custom_menu.html)

<ul class="nav">
        {% for app in custom_apps %}
        <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
                {% trans app.name %}<b class="caret"></b>
            </a>

        <ul class="dropdown-menu">
            {% for model in app.models %}
            <li><a href="/{{ model.admin_url }}">{{ model.name }}</a></li>
            {% endfor %}
        </ul>
        </li>
    {% endfor %}
</ul>

templates/admin/base.html 的顶部我有{% load custom_menu %},在应该显示菜单的地方我有{% custom_app_list request %}

【问题讨论】:

  • 您的错误似乎与您提供的代码不匹配。您确定您使用的是{% load custom_menu %} 而不是{% load custom_app_list %}?如果您已更改它,请确保您已重新加载服务器,并使用实际错误更新您的问题。
  • 是的,你是对的@Alasdair!我更新了我的代码和错误。我刚刚改了你说的,忘记更新错误了。
  • 您可能无需太多更改就可以让代码在 Django 1.6 中工作。应用程序在 Django 1.7 中发生了很大变化,所以这可能会更棘手。

标签: python django django-admin django-templates django-apps


【解决方案1】:

此导入无效,因此引发ImportError

from django.contrib.admin.validation import validate

模块django.contrib.admin.validation 不包含函数validate。它有一个BaseValidator 对象,它有一个validate 方法。

我不清楚你为什么要导入validate。尝试删除导入,以及从模板标记中调用 validate 的行。

对于第二个错误,您需要确保 request 在模板上下文中。最简单的方法是将request template context processor 添加到您的TEMPLATE_CONTEXT_PROCESSORS 设置中。

【讨论】:

  • 嗯做到了,现在我得到了'str' object has no attribute 'user'{% custom_app_list request %} 有问题。我认为代码(您可以在问题中找到链接)有点旧,所以我不确定从那以后发生了什么变化。
  • 是的,你是对的。谢谢!将请求添加到模板上下文并且它现在可以工作,即使它仍然没有显示应用程序,但我想我必须修复这两个。有什么方法可以在不更改任何设置(不添加请求)的情况下做到这一点?
  • 模板标签需要请求对象才能检查用户的权限。您可以更改所有管理视图以在模板上下文中包含 request,但使用模板上下文处理器要容易得多。
  • 我解决了这个问题,现在可以正常工作了,再次感谢您!问题是我正计划为该项目创建一个包,并且我试图让它尽可能简单,所以我不希望用户更改他们的设置(除了在INSTALLED_APPS 中添加应用程序。那是我想避免使用模板上下文处理器的原因。
  • 出于我之前给出的原因,我认为您实际上无法避免必须添加模板上下文处理器。在安装 Django 应用程序时,必须向中间件或模板上下文处理器添加一个条目是很常见的,所以我不会太担心。
猜你喜欢
  • 1970-01-01
  • 2013-08-01
  • 2019-11-26
  • 2023-04-03
  • 1970-01-01
  • 2012-03-15
  • 2010-11-03
  • 2021-02-05
  • 2014-04-24
相关资源
最近更新 更多