【问题标题】:In Django admin, how can I hide Save and Continue and Save and Add Another buttons on a model admin?在 Django 管理员中,如何在模型管理员上隐藏“保存并继续”和“保存并添加另一个”按钮?
【发布时间】:2012-10-17 13:35:41
【问题描述】:

我在 Django 管理员中有一个模型的工作流程,它与用户的工作流程非常相似。首先,我有一个包含基本字段的表单,然后是包含其余数据的第二个表单。

与 auth.user 的工作流程相同

我需要删除“保存并继续”和“保存并添加另一个”按钮,以防止用户破坏工作流程。

我已尝试将其添加为 extra_context

extra_context = {
  'show_save_and_add_another': False,
  'show_save_and_continue': False
}

并通过 ModelAdmin.add_view 或 ModelAdmin.change_view 传递它,但它不起作用。

这仅适用于一个模型,所以我不想从 submit_line.html 中删除

有什么线索或替代方法吗?

提前致谢

【问题讨论】:

    标签: python django django-templates django-admin


    【解决方案1】:

    据我所知,使用“开箱即用”选项是不可能的,但这就是我要做的事情。

    我们关心的代码位是this templatetag - 无论您将其设置为什么,这似乎都会覆盖show_save_and_add_anothershow_save_and_continue。它还创建了一个全新的上下文并仅复制某些值(不清楚这样做的理由是什么),因此您必须对其进行修改以获得所需的内容。

    所以:

    1. 创建一个模板标签来复制默认标签的功能,可以通过重用现有标签(参见okm's example)或完全复制它。这里唯一的变化是它应该将您的 show_save_and_add_another 保留在原始上下文中而不覆盖它,或者传递您自己的 really_hide_save_and_add_another_damnit 上下文变量。
    2. 替换 change_form.html 以包含并使用您自己的模板标签,用它替换 submit_row
    3. 如果您选择使用额外的上下文变量,用另一个条件语句包装按钮,请更新 change_form.html。

    然后,无论您选择什么选项,都将您的 ModelAdmin 更新为类似(基于this from the Django docs):

    class MyModelAdmin(admin.ModelAdmin):
        # ...
        def change_view(self, request, object_id, form_url='', extra_context=None):
            extra_context = extra_context or {}
            extra_context['show_save_and_add_another'] = False
            # or
            extra_context['really_hide_save_and_add_another_damnit'] = True
            return super(MyModelAdmin, self).change_view(request, object_id,
                form_url, extra_context=extra_context)
    

    更新:原始响应没有考虑到 submit_row 没有传递任何完整的原始上下文。

    【讨论】:

    • 它运行良好,我可以在 change_form.html 上测试我的 'really_hide_save_and_add_another_damnit' 新变量,但似乎我无法在 submit_line.html 中执行此操作,因为它的值在所有情况下都是 ''。我尝试过测试、检查、打印……但没有成功的值。我需要在模板开头加载任何附加库吗?
    • 对不起,我没有意识到 submit_row 模板标签不会复制整个上下文 - 只是某些项目。您需要完全覆盖这个模板标签,或者使用 okm 的选项。
    【解决方案2】:

    除了它(有点尴尬)的黑客风格之外,您还可以直接覆盖模板标签。 通常更推荐覆盖模板。

    # put this in some app such as customize/templatetags/admin_modify.py and place the app
    # before the 'django.contrib.admin' in the INSTALLED_APPS in settings
    
    from django.contrib.admin.templatetags.admin_modify import *
    from django.contrib.admin.templatetags.admin_modify import submit_row as original_submit_row
    # or 
    # original_submit_row = submit_row
    
    @register.inclusion_tag('admin/submit_line.html', takes_context=True)
    def submit_row(context):
        ctx = original_submit_row(context)
        ctx.update({
            'show_save_and_add_another': context.get('show_save_and_add_another', ctx['show_save_and_add_another']),
            'show_save_and_continue': context.get('show_save_and_continue', ctx['show_save_and_continue'])
            })                                                                  
        return ctx 
    

    【讨论】:

    • 我认为这实际上是最好的方法。首先,我尝试按照您在# put this in some app such as customize/templatetags/admin_modify.py ... 中解释的操作,但没有成功。然后,我把这段代码放在 admin.py 文件的开头,就完美了。
    • @ManuelAlvarez 很好。也许您的customize/templatetags/ 缺少__init__.py,因此不是一个包并被忽略。我不太确定您的admin.py 解决方案是否适用于所有情况,我们会看到:)
    • import * 的目的是什么?我试图删除它,并一一导入所有这些函数,但是不再调用我的自定义 submit_row 方法。知道为什么吗?
    • @NiCU 这是导入所有必需品的快速输入。一个一个地导入比较合适。也许您的标签不会覆盖原始标签,因为您的自定义应用程序位于 INSTALLED_APPS 中的原始应用程序之后?
    • 是的,我有一些问题,现在它已经修复了(嗯...我想我应该删除我的 cmets,因为不是真的有用)
    【解决方案3】:

    一种非常不同的方法是在 /static/admin/css/base.css

    input[name="_addanother"],input[name="_continue"],input[name="_saveasnew"]{
        display: none;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-13
      • 2014-11-18
      • 2012-01-25
      • 2015-03-27
      • 2011-04-08
      • 2018-07-23
      • 1970-01-01
      • 2011-03-30
      相关资源
      最近更新 更多