“无法隐藏”;保存并添加另一个";Django管理中的按钮

“无法隐藏”;保存并添加另一个";Django管理中的按钮,django,django-templates,Django,Django Templates,我想隐藏Django的管理员更改表单中的所有“保存”按钮,对于特定的模型,当满足某些条件时。因此,我覆盖了相关的ModelAdmin中的changeform\u视图方法,如下所示: def changeform_view(self, request, object_id=None, form_url='', extra_context=None): extra_context = extra_context or {} obj = collection_management_Ma

我想隐藏Django的管理员更改表单中的所有“保存”按钮,对于特定的模型,当满足某些条件时。因此,我覆盖了相关的
ModelAdmin
中的
changeform\u视图
方法,如下所示:

def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
    extra_context = extra_context or {}
    obj = collection_management_MammalianLine.objects.get(pk=object_id)
    if obj:
        if not (request.user.is_superuser or request.user.groups.filter(name='Lab manager').exists() or request.user == obj.created_by):
            extra_context['show_save'] = False
            extra_context['show_save_and_continue'] = False
            extra_context['show_save_and_add_another'] = False
        else:
            pass
    else:
        pass
    return super(MammalianLinePage, self).changeform_view(request, object_id, extra_context=extra_context)
有了这段代码,我可以成功地隐藏“保存”和“保存并继续”按钮,但不能隐藏“保存并添加另一个”按钮。我可以看到
submit\u line.html
包含以下三行

{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" />{% endif %}
{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" />{% endif %}
{% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" />{% endif %}
{%if show\u save%}{%endif%}
{%if显示\保存\和\添加\另一个%}{%endif%}
{%if show_save_and_continue%}{%endif%}

我的问题是:为什么我可以隐藏“保存”和“保存并继续”按钮,而不能隐藏“保存并添加另一个”按钮?即使相关的templatetag(show_save_和_continue)在模板中。

在传递的上下文中检查除
show_save_和_continue
之外的其他键。德扬戈

您可以修补
submit\u row
template tag函数,首先检查
context
字典中的
show\u save\u和\u add\u另一个

@register.inclusion_tag('admin/submit_line.html', takes_context=True)
def submit_row(context):
    """
    Display the row of buttons for delete and save.
    """
    change = context['change']
    is_popup = context['is_popup']
    save_as = context['save_as']
    show_save = context.get('show_save', True)
    show_save_and_continue = context.get('show_save_and_continue', True)
    show_save_and_add_another = context.get('show_save_and_add_another', False)
    ctx = Context(context)
    ctx.update({
        'show_delete_link': (
            not is_popup and context['has_delete_permission'] and
            change and context.get('show_delete', True)
        ),
        'show_save_as_new': not is_popup and change and save_as,
        'show_save_and_add_another': (
            context.get('show_save_and_add_another', None) or
            (context['has_add_permission'] and not is_popup and
            (not save_as or context['add']))
        ),
        'show_save_and_continue': not is_popup and context['has_change_permission'] and show_save_and_continue,
        'show_save': show_save,
    })
    return ctx
编辑

(function($) {
'use strict';
$(document).ready(function() {
    // hide the "Save and add another" button
    $("input[name='_addanother']").attr('type','hidden');
});
})(django.jQuery);
修补“admin/submit\line.html”包含标记的步骤

  • models.py
    views.py的同一级别创建
    templatetags
    文件夹

  • templatetags
    文件夹中创建
    \uuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

  • 复制到
    模板标签/admin\u modify.py

  • 用上面的函数定义覆盖
    submit\u行
    函数定义

  • 注意这适用于Django 2.0及以下版本

    对于最近的Django版本,请查找允许此表达式为
    False
    的上下文组合


    .

    我有另一种方法隐藏“保存并添加另一个”按钮

    格式为.py

    class TestForm(forms.ModelForm):
        class Media:
              js = ('admin/yourjsfile.js',)
    
    在yourjsfile.js中

    (function($) {
    'use strict';
    $(document).ready(function() {
        // hide the "Save and add another" button
        $("input[name='_addanother']").attr('type','hidden');
    });
    })(django.jQuery);
    
    我隐藏那个按钮也有同样的问题。 我已经在Django 1.11中对其进行了测试,它确实有效,但我认为有更好的方法来实现它。

    EDIT: 从Django 3.1开始,来自的方法应该只起作用:

    ...
    extra_context['show_save_and_add_another'] = False
    ...
    
    有关详细信息,请参阅

    旧答案: 总结 其他一些选择:

  • 在您的
    ModelAdmin
    上设置
    save_as=True
    。如中所述,这将用“另存为新”按钮替换“保存并添加另一个”按钮。这可能不适合所有情况,但据我所知,这是最简单的解决方案

  • 在您的
    ModelAdmin
    上为
    has\u add\u permission
    方法应用一个monkey补丁,因此在调用
    super()期间它返回
    False
    。更改视图
    (或
    changeform\u视图

  • 覆盖
    TemplateResponse.content
    ()以从HTML中隐藏(或删除)包含按钮的
    submit行
    元素

  • 详细信息选项1 最简单的选项是在
    ModelAdmin
    上设置
    save_as=True
    。这将用“另存为新”按钮替换“保存并添加另一个”按钮。因此,假设已禁用其他保存按钮,则对当前对象所做的任何更改只能保存为新对象。当前对象将保持不变

    基本实施:

    class MyModelAdmin(ModelAdmin):
        save_as = True
    
        # your other code here, such as the extended changeform_view 
    
    详细信息选项2 该模板显示用于显示/隐藏保存和删除按钮的上下文变量。大多数上下文变量可以通过
    changeform\u视图
    (或
    change\u视图
    )中的
    extra\u上下文
    进行设置。但是,正如OP所示,我们不能简单地以这种方式覆盖
    show\u save\u和\u add\u另一个

    正如他在答复中指出的那样,
    show\u save\u和\u add\u中设置了另一个
    ,这将为创建上下文

    仔细检查源代码后,很可能会覆盖
    has\u add\u permission
    上下文变量,因为这决定了
    show\u save\u和\u add\u另一个
    的值。但是,在
    Django<2.1
    中,简单地将
    添加到
    额外上下文中就不起作用,因为该方法将撤消更改

    幸运的是,我们不需要重写模板或修补模板标记,只需使用in
    change\u视图
    ,诱使Django认为
    具有添加权限
    False

    def change_view(self, request, object_id=None, form_url='', extra_context=None):
        # use extra_context to disable the other save (and/or delete) buttons
        extra_context = dict(show_save=False, show_save_and_continue=False, show_delete=False)
        # get a reference to the original has_add_permission method
        has_add_permission = self.has_add_permission
        # monkey patch: temporarily override has_add_permission so it returns False
        self.has_add_permission = lambda __: False
        # get the TemplateResponse from super (python 3)
        template_response = super().change_view(request, object_id, form_url, extra_context)
        # restore the original has_add_permission (otherwise we cannot add anymore)
        self.has_add_permission = has_add_permission
        # return the result
        return template_response
    
    def change_view(self, request, object_id=None, form_url='',
                    extra_context=None):
        # get the default template response
        template_response = super().change_view(request, object_id, form_url,
                                                extra_context)
        # here we simply hide the div that contains the save and delete buttons
        template_response.content = template_response.rendered_content.replace(
            '<div class="submit-row">',
            '<div class="submit-row" style="display: none">')
        return template_response
    
    如果将OP()使用的
    changeform\u视图
    替换为
    changeform\u视图
    ,也可以使用此功能

    注意:显然,只有在
    具有\u add\u permission=False的情况下才能使用此选项
    不会干扰更改视图中的其他内容

    详细信息选项3 基于此,还可以简单地从
    change\u视图
    的呈现HTML中隐藏(甚至删除)提交行

    def change_view(self, request, object_id=None, form_url='', extra_context=None):
        # use extra_context to disable the other save (and/or delete) buttons
        extra_context = dict(show_save=False, show_save_and_continue=False, show_delete=False)
        # get a reference to the original has_add_permission method
        has_add_permission = self.has_add_permission
        # monkey patch: temporarily override has_add_permission so it returns False
        self.has_add_permission = lambda __: False
        # get the TemplateResponse from super (python 3)
        template_response = super().change_view(request, object_id, form_url, extra_context)
        # restore the original has_add_permission (otherwise we cannot add anymore)
        self.has_add_permission = has_add_permission
        # return the result
        return template_response
    
    def change_view(self, request, object_id=None, form_url='',
                    extra_context=None):
        # get the default template response
        template_response = super().change_view(request, object_id, form_url,
                                                extra_context)
        # here we simply hide the div that contains the save and delete buttons
        template_response.content = template_response.rendered_content.replace(
            '<div class="submit-row">',
            '<div class="submit-row" style="display: none">')
        return template_response
    
    def change\u view(self,request,object\u id=None,form\u url='',
    额外上下文=无):
    #获取默认模板响应
    template\u response=super()。更改视图(请求、对象id、表单url、,
    额外(上下文)
    #这里我们只是隐藏包含save和delete按钮的div
    template\u response.content=template\u response.rendered\u content.replace(
    '',
    '')
    返回模板\u响应
    
    如前所述,我们还可以删除
    submitrow
    部分,但这需要做更多的工作


    这比选项2简单,但更脆弱。

    您可以覆盖ModelAdmin子类中的render\u change\u form方法。 在此方法中,obj作为参数可用,您可以检查某些条件

    class OrderAdmin(admin.ModelAdmin):
    
        def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
            context.update({
                'show_save': False,
                'show_save_and_continue': False,
                'show_delete': False
            })
            return super().render_change_form(request, context, add, change, form_url, obj)
    
    我建议(更改了djvg答案的选项3)使用regex删除此html输入元素,如下例所示:

    class MyModelAdmin(admin.ModelAdmin):
    
        def add_view(self, request, form_url='', extra_context=None):
            template_response = super(MyModelAdmin, self).add_view(
                request, form_url=form_url, extra_context=extra_context)
            # POST request won't have html response
            if request.method == 'GET':
                # removing Save and add another button: with regex
                template_response.content = re.sub("<input.*?_addanother.*?(/>|>)", "", template_response.rendered_content)
            return template_response
    
    类MyModelAdmin(admin.ModelAdmin):
    def add_视图(self、request、form_url=''、extra_context=None):