28

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

我已经检查了如何重载管理模板,但我仍然不知道,我应该把我的视图函数放在哪里我会做我的事情,以及如何将该视图注册到管理 url。

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

我找到了这个,但我不知道这是否是正确的方法: http: //www.stavros.io/posts/how-to-extend-the-django-admin-site-with-custom/

4

2 回答 2

66

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

确保您的应用'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 的内容path/to/your/site-packages/django/contrib/admin/templates/admin/change_list.html另一个答案还向您展示了如何格式化模板。Nikolai Saiko 向您展示了如何使用 'extends' 和 'super' 覆盖相关部分。概括:

{% 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 %}

让我们填写href="..."一个网址。管理员 url 名称位于命名空间 'admin' 中,可以像这样查找:

{% url 'admin:custom_view' %}

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

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

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

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"

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

您可以保护您的视图,并且只向具有员工身份的用户授予访问权限:

from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
def my_view(request):
    ...

您可能还想检查request.user.is_active和处理非活动用户。

更新:利用框架并尽可能少地进行定制。很多时候操作可能是一个不错的选择:https ://docs.djangoproject.com/en/1.5/ref/contrib/admin/actions/

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

于 2013-07-29T10:43:13.567 回答
15

这是另一种解决方案,不使用 jQuery(如 allcaps 提供的)。此解决方案还以更直观的方式提供对象的 pk :)

我将根据该链接提供我的源代码(点击上面的链接了解更多信息):

我有一个带有模型产品的应用产品。此代码添加按钮“Do Evil”,该按钮执行 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 >= 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 %}  
于 2014-07-03T12:37:00.763 回答