将链接添加到自定义django管理员视图

时间:2018-12-10 19:56:30

标签: django django-admin

我已创建here中所述的自定义管理员视图。

class MyAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('stats/', self.admin_site.admin_view(self.stats)),
        ]
        return my_urls + urls

    def stats(self, request):
        request.current_app = self.admin_site.name

        context = dict(
           # Include common variables for rendering the admin template.
           self.admin_site.each_context(request),
           # Anything else you want in the context...
           key='blah',
        )
        return TemplateResponse(request, "sometemplate.html", context)

URL正在工作并且正在加载模板。 但是,如何获得指向Django管理员概述的新自定义视图的链接?

enter image description here

2 个答案:

答案 0 :(得分:0)

虽然不是一个好方法,但是您可以尝试将django管理员的默认index.html覆盖为:

   {% for model in app.models %}
        <tr class="model-{{ model.object_name|lower }}">
        {% if model.admin_url %}
            <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
        {% else %}
            <th scope="row">{{ model.name }}</th>
        {% endif %}

        {% if model.add_url %}
            <td><a href="{{ model.add_url }}" class="addlink">{% trans 'Add' %}</a></td>
        {% else %}
            <td>&nbsp;</td>
        {% endif %}

        {% if model.admin_url %}
            <td><a href="{{ model.admin_url }}" class="changelink">{% trans 'Change' %}</a></td>
        {% else %}
            <td>&nbsp;</td>
        {% endif %}
        </tr>

   {% endfor %}
    <!-- extra link you want to display -->
    <tr>
    <th scope="row"><a href="link_url">link_name</a></th>
    <td><a href="link_url" class="changelink">{% trans 'Change' %}</a></td>
    </tr>

在覆盖此块之后,将index.html放入项目的template / admin目录中。希望这会有所帮助。

答案 1 :(得分:0)

已经有一个类似的问题How do you add a new entry into the django admin index?,但是提供的所有答案对我来说都不是很满意。

因此,我遍历了源代码,并一直在寻找一种可能不会覆盖任何模板的可能性,无论是index.html还是app_index.html

文件django/contrib/admin/sites.py包含负责渲染index.htmlapp_index.html的代码,第一个是显示问题中所说明内容的模板。

方法index呈现模板index.html并显示具有注册模型管理员的可用应用程序。它使用方法get_app_list来获取应用程序。在此方法中,将调用方法_build_app_dict,该方法将获取模型和模型管理员。

方法app_index呈现模板app_index.html并显示单个应用程序的注册模型管理员。它使用前面提到的方法_build_app_dict

因此,我决定在自定义管理员中覆盖此方法。根据问题中的示例,它看起来可能像这样(与原始示例的差异以粗体显示):

class MyAdmin(admin.AdminSite):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('stats/', self.admin_site.admin_view(self.stats), name='stats'),
        ]
        return my_urls + urls

    def stats(self, request):
        request.current_app = self.admin_site.name

        context = dict(
           # Include common variables for rendering the admin template.
           self.admin_site.each_context(request),
           # Anything else you want in the context...
           key='blah',
        )
        return TemplateResponse(request, "sometemplate.html", context)

    def _build_app_dict(self, request, label=None):
        # we create manually a dict to fake a model for our view 'stats'
        # this is an example how the dict should look like, i.e. which keys
        # should be present, the actual values may vary
        stats = {
            'name': 'Stats',
            'admin_url': reverse('my_admin:stats'),
            'object_name': 'Stats',
            'perms': {'delete': False, 'add': False, 'change': False},
            'add_url': ''
        }
        # get the app dict from the parent method
        app_dict = super(MyAdmin, self)._build_app_dict(request, label)
        # check if there is value for label, then the app_index will be rendered
        if label:
            # append the manually created dictionary 'stats'
            app_dict['models'].append(stats)
        # otherwise the index will be rendered
        # and we have to get the entry for our app,
        # which is in this case 'traffic'
        # using TrafficConfig.name or TrafficConfig.label
        # might be better than hard coding the value
        else:
            app = app_dict.get('traffic', None)
            # if an entry for 'traffic' has been found
            # we append our manually created dictionary
            if app:
                app['models'].append(stats)
        return app_dict

my_admin = MyAdmin(name='my_admin')
my_admin.register(Traffic)

现在,当我们打开自定义管理员时,我们将看到以下内容:


TRAFFIC
---------------------------------  
  Traffics    + Add   \ Change  
  Stats               \ Change  

这是因为我们处理了用于呈现模板的字典,并且使用了我们指定的值,在这种情况下,最相关的是name 统计信息,即{{1} },它将调用自定义视图admin_url。由于我们将stats留为空白,因此不会显示 +添加链接。

重要的也是倒数第二行,我们将其称为自定义admin并将名称传递给它,它将用作url命名空间。

编辑:
不幸的是,我仅在发布答案后才注意到问题在询问如何显示在add_url中创建的自定义视图的链接,而我的答案说明了如何针对自定义管理员ModelAdmin执行此操作。希望对您有所帮助。