我想在我的模型的模型列表视图中的“添加”按钮旁边添加一个按钮,然后创建一个视图函数,我将完成我的工作,然后将用户重定向回列表视图。
我已经检查过如何重载管理模板,但我仍然不知道,我应该把我的视图功能放在哪里我会做我的东西,以及如何将该视图注册到管理网址。
还有关于安全性的问题。我想在管理员内部执行该操作,因此如果您未登录,则无法使用它。
我发现了这一点,但我不知道这是否正确:http://www.stavros.io/posts/how-to-extend-the-django-admin-site-with-custom/
答案 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 %}