如何在django管理员更改列表视图页面中添加按钮

时间:2013-07-29 08:33:44

标签: django django-admin

我想在我的模型的模型列表视图中的“添加”按钮旁边添加一个按钮,然后创建一个视图函数,我将完成我的工作,然后将用户重定向回列表视图。

我已经检查过如何重载管理模板,但我仍然不知道,我应该把我的视图功能放在哪里我会做我的东西,以及如何将该视图注册到管理网址。

还有关于安全性的问题。我想在管理员内部执行该操作,因此如果您未登录,则无法使用它。

我发现了这一点,但我不知道这是否正确:http://www.stavros.io/posts/how-to-extend-the-django-admin-site-with-custom/

2 个答案:

答案 0 :(得分:46)

  

当多个应用程序提供相同版本的不同版本时   资源(模板,静态文件,管理命令,翻译),   首先在INSTALLED_APPS中列出的应用程序具有优先权。    - Django documentation on INSTALLED_APPS

确保您的应用在[{1}} {。}} 'django.contrib.admin'之前列出。

在以下目录之一中创建INSTALLED_APPS模板:

change_list.html

模板应该自动拾取,但如果它不在上面列出的路径之一上,您也可以通过管理模型属性指向它:

# Template applies to all change lists.
myproject/myapp/templates/admin/change_list.html      

# Template applies to change lists in myapp.
myproject/myapp/templates/admin/myapp/change_list.html  

# Template applies to change list in myapp and only to the Foo model.
myproject/myapp/templates/admin/myapp/foo/change_list.html  

您可以在class MyModelAdmin(admin.ModelAdmin): #... change_list_template = "path/to/change_list.html" 中查找原始change_list.html的内容。 The other answer还会向您展示如何格式化模板。 Nikolai Saiko向您展示如何使用'extends'和'super'覆盖相关部分。总结:

path/to/your/site-packages/django/contrib/admin/templates/admin/change_list.html

让我们用网址填充{% extends "admin/change_list.html" %} {% load i18n %} {% block object-tools-items %} {{ block.super }} <li> <a class="historylink" href="...">My custom admin page</a> </li> {% endblock %} 。管理员网址名称位于命名空间“admin”中,可以像这样查找:

href="..."

当您向change_form.html添加按钮时,您可能希望传入当前对象ID:

{% url 'admin:custom_view' %}

现在创建一个自定义视图。这可以是常规视图(就像您网站上的其他页面一样)或admin.py中的自定义管理视图。 ModelAdmin上的get_urls方法以与URLconf相同的方式返回要用于该ModelAdmin的URL。因此,您可以按照URL调度程序中的说明扩展它们:

{% url 'admin:custom_view' original.pk %}

阅读有关如何在ModelAdmin中为视图设置权​​限的文档:https://docs.djangoproject.com/en/1.5/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_urls

您可以保护自己的观点,只允许具有员工身份的用户访问:

class MyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super(MyModelAdmin, self).get_urls()
        my_urls = patterns('',
            url(r'^my_view/$', self.my_view, name="custom_view")
        )
        return my_urls + urls

    def my_view(self, request):
        # custom view which should return an HttpResponse
        pass

    # In case your template resides in a non-standard location
    change_list_template = "path/to/change_list.html"

您可能还想检查from django.contrib.admin.views.decorators import staff_member_required @staff_member_required def my_view(request): ... 并处理非活动用户。

更新:利用框架并尽可能少地进行自定义。很多时候,行动可能是一个很好的选择:https://docs.djangoproject.com/en/1.5/ref/contrib/admin/actions/

更新2:我删除了一个JS示例来注入按钮客户端。如果需要,请参阅the revisions

答案 1 :(得分:14)

这里是another solution,没有使用jQuery(就像allcaps提供的一样)。此解决方案还为对象的pk提供了更直观的方式:)

我会根据该链接提供我的源代码(请点击上面的链接获取更多信息):

我有一个带有型号产品的应用产品。此代码添加了按钮&#34; Do Evil&#34;,执行ProductAdmin.do_evil_view()

文件 products / models.py

class ProductAdmin(admin.ModelAdmin):   
    def get_urls(self):
        urls = super().get_urls()
        my_urls = patterns('',
            (r'^(?P<pk>\d+)/evilUrl/$', self.admin_site.admin_view(self.do_evil_view))
        )
        return my_urls + urls

    def do_evil_view(self, request, pk):
        print('doing evil with', Product.objects.get(pk=int(pk)))
        return redirect('/admin/products/product/%s/' % pk)
需要

self.admin_site.admin_view 以确保以管理员身份登录用户。

这是标准Django管理页面的模板扩展,用于更改条目:
文件: {template_dir} /admin/products/product/change_form.html

Django&gt; = 1.8 (感谢@jenniwren提供此信息):

{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools-items %}
    {{ block.super }}
    <li><a class="historylink" href="evilUrl/">{% trans "Do Evil" %}</a></li>
{% endblock %}

如果 Django版本小于1.8 ,则必须编写更多代码:

{% extends "admin/change_form.html" %}
{% load i18n %}
{% block object-tools %}
{% if change %}{% if not is_popup %}
<ul class="object-tools">
    <li><a class="historylink" href="history/">{% trans "History" %}</a></li>
    <li><a class="historylink" href="evilUrl/">{% trans "Do Evil" %}</a></li>
{% if has_absolute_url %}
    <li><a class="viewsitelink" href="../../../r/{{ content_type_id }}/{{ object_id }}/">{% trans "View on site" %}</a></li>
{% endif%}</ul>
{% endif %}{% endif %}
{% endblock %}