从模型创建表单中的相关模型字段中删除 'Delete selected model' 按钮(Django 管理)

Remove 'Delete selected model' button from related model fields in model creation form (Django admin)

在我的模型中,我有 Document 模型,外键指向 Library 模型。 当我在 Django 管理站点时,我想在创建新 Document.

时禁用编辑和删除 Library 实例

我尝试的是通过继承 django.contrib.admin.ModelAdmin 并删除 change/delete 权限来删除删除和编辑权限

@admin.register(Library)
class LibraryAdmin(admin.ModelAdmin):
    def has_delete_permission(self, request, obj=None):
        return False

    def has_change_permission(self, request, obj=None):
        return False

这会使不需要的按钮消失,但也完全阻止了编辑和删除 Libraries 的可能性,这不是我想要的。有没有办法仅在模型编辑表单中禁用这些操作?

您可以在文档管理员中标记请求:

def changeform_view(self, request, object_id=None, form_url='', extra_context=None):
    request._editing_document = object_id is not None  # add attribute
    return super(DocumentAdmin, self).changeform_view(request, object_id=object_id, form_url=form_url, extra_context=extra_context)

现在您可以在相关管理员中访问该标志:

@admin.register(Library)
class LibraryAdmin(admin.ModelAdmin):
    def has_delete_permission(self, request, obj=None):
        if getattr(request, '_editing_document', False):  # query attribute
            return False
        return super(LibraryAdmin, self).has_delete_permission(request, obj=obj)

另一个类似于 schwobaseggl 的变体是:

@admin.register(Library)
class LibraryAdmin(admin.ModelAdmin):
    def has_delete_permission(self, request, obj=None):
        r = super(LibraryAdmin, self).has_delete_permission(request,obj)
        if r:
            referer = request.path
            
            # Here we can check all the forms were we don`t want to allow Library deletion
            if 'documentappname/document/' in referer:
                r = False
        
        return r

优点:只做一个功能,可以避免在不同型号的很多编辑页面中删除。
缺点: 它依赖于您的管理应用程序的 url 模式,因此,如果它更改了应用程序或模型名称(奇怪但可能),您将不得不更改它。另一个缺点是粒度不那么细:您不能根据要删除的对象的某些 属性 选择避免删除。你可以用 schwobaseggl 的建议来做到这一点。