django - 有没有办法覆盖 ModelAdmin 中的 delete_selected 方法但保持确认?

标签 django django-rest-framework django-admin

我有:

class Person(admin.ModelAdmin):
    actions = ['delete_selected']
    def delete_selected(modeladmin, request, queryset):
        # Show confirmation page.
        for obj in queryset:
            obj.custom_delete()

我在那里留下的评论是我挣扎的地方。在执行自定义删除之前,我仍然想显示确认页面。

最佳答案

简短回答 :您应该覆盖 delete_queryset [Django-doc] ,因为这封装了删除对象的真实逻辑。

您不应覆盖 delete_selected 。这个 Action 是 defined like [GitHub] :

def delete_selected(modeladmin, request, queryset):

    # ...

    # Populate deletable_objects, a data structure of all related objects that
    # will also be deleted.
    deletable_objects, model_count, perms_needed, protected = modeladmin.get_deleted_objects(queryset, request)

    # The user has already confirmed the deletion.
    # Do the deletion and return None to display the change list view again.
    if request.POST.get('post') and not protected:
        if perms_needed:
            raise PermissionDenied
        n = queryset.count()
        if n:
            for obj in queryset:
                obj_display = str(obj)
                modeladmin.log_deletion(request, obj, obj_display)
            modeladmin.delete_queryset(request, queryset)
            modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % {
                "count": n, "items": model_ngettext(modeladmin.opts, n)
            }, messages.SUCCESS)
        # Return None to display the change list page again.
        return None

    # ...

    context = {
        # ...
    }

    request.current_app = modeladmin.admin_site.name

    # Display the confirmation page
    return TemplateResponse(request, modeladmin.delete_selected_confirmation_template or [
        "admin/%s/%s/delete_selected_confirmation.html" % (app_label, opts.model_name),
        "admin/%s/delete_selected_confirmation.html" % app_label,
        "admin/delete_selected_confirmation.html"
    ], context)


delete_selected.allowed_permissions = ('delete',)
delete_selected.short_description = gettext_lazy("Delete selected %(verbose_name_plural)s")


这里的关键部分是此操作将执行适当的检查,但删除本身是通过调用完成的:

            modeladmin.delete_queryset(request, queryset)


因此,使用以下命令覆盖 delete_queryset 就足够了:
class PersonAdmin(admin.ModelAdmin):

    actions = ['delete_selected']

    def delete_queryset(self, request, queryset):
        for obj in queryset:
            obj.custom_delete()

一个 ModelAdmin 有一个 standard implementation for delete_queryset [GitHub] :

class ModelAdmin(BaseModelAdmin):

    # ...

    def delete_queryset(self, request, queryset):
        """Given a queryset, delete it from the database."""
        queryset.delete()

关于django - 有没有办法覆盖 ModelAdmin 中的 delete_selected 方法但保持确认?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56450998/

相关文章:

python - 在 django 上使用 mako 时如何处理国际化,

python - Django rest framework 嵌套序列化器部分更新

jquery - 如何使用 Django、Ajax、jQuery 提交表单而不刷新页面?

django - 在 Django context_processor 中测试 request.resolver_match

python - Django rest 框架单元测试 View 集 mixins

python - DRF - 设置序列化程序字段的最大值和最小值

javascript - Django MongoEngine CORS 错误

python - 在 Django search_fields 上实现自定义函数

django admin fieldsets - 添加相关模型的字段

Django-管理员中的UserProfile m2m字段-错误