arj*_*jun 17 django django-admin
我有admin.py如下:
class profilesAdmin(admin.ModelAdmin):
list_display = ["type","username","domain_name"]
Run Code Online (Sandbox Code Playgroud)
现在我想在删除对象之前执行一些操作:
class profilesAdmin(admin.ModelAdmin):
list_display = ["type","username","domain_name"]
@receiver(pre_delete, sender=profile)
def _profile_delete(sender, instance, **kwargs):
filename=object.profile_name+".xml"
os.remove(os.path.join(object.type,filename))
Run Code Online (Sandbox Code Playgroud)
如果我使用像这样的删除信号方法我得到一个错误说self应该是第一个参数.
如何修改上述功能?
我想检索被删除对象的profile_name.如何才能做到这一点?
我也尝试重写delete_model方法:
def delete_model(self, request, object):
filename=object.profile_name+".xml"
os.remove(os.path.join(object.type,filename))
object.delete()
Run Code Online (Sandbox Code Playgroud)
但如果必须一次删除多个对象,这不起作用.
Kus*_*era 19
您可以使用delete_queryset这是来自Django的2.1起批量删除对象和delete_model单删除。这两种方法都会在删除对象之前处理一些事情。
这是关于解释delete_queryset在发行说明中的Django 2.1。
delete_queryset() 方法被赋予 HttpRequest 和要删除的对象的 QuerySet。覆盖此方法以自定义“删除选定对象”的删除过程
让我们看看delete_queryset做了什么,你可以覆盖 admin。ModelAdmin类以这种方式包含delete_queryset函数。在这里你会得到对象列表,queryset.delete()意思是一次删除所有对象,或者你可以添加一个循环来一个一个地删除。
def delete_queryset(self, request, queryset):
print('==========================delete_queryset==========================')
print(queryset)
"""
you can do anything here BEFORE deleting the object(s)
"""
queryset.delete()
"""
you can do anything here AFTER deleting the object(s)
"""
print('==========================delete_queryset==========================')
Run Code Online (Sandbox Code Playgroud)
所以我要从“选择窗口”中删除 5 个对象,这是这 5 个对象。
然后你会像这样重定向到确认页面,
请记住“是的,我确定”按钮,稍后我会解释。当您单击该按钮时,您将在删除这 5 个对象后看到下图。
这是终端输出,
所以你会得到这 5 个对象作为 QuerySet 的列表,在删除之前你可以在评论区做任何你想做的事情。
这是关于delete_model的解释。
delete_model 方法被赋予了 HttpRequest 和一个模型实例。覆盖此方法允许执行删除前或删除后操作。调用 super().delete_model() 以使用 Model.delete() 删除对象。
让我们看看delete_model做了什么,你可以覆盖admin。ModelAdmin类以这种方式包含delete_model函数。
actions = ['delete_model']
def delete_model(self, request, obj):
print('============================delete_model============================')
print(obj)
"""
you can do anything here BEFORE deleting the object
"""
obj.delete()
"""
you can do anything here AFTER deleting the object
"""
print('============================delete_model============================')
Run Code Online (Sandbox Code Playgroud)
我只需单击我的第 6 个对象即可从“更改窗口”中删除。
还有另一个删除按钮,当您单击它时,您将看到我们之前看到的窗口。
单击“是的,我确定”按钮删除单个对象。您将看到以下窗口,其中包含该已删除对象的通知。
这是终端输出,
因此,您将获得所选对象作为 QuerySet 的单个对象,并且在删除之前您可以在评论区中做任何您想做的事情。
在最后的结论是,你可以通过点击“是的,我确定”,在“选择窗口”,“变更窗口”在Django管理站点按钮或使用处理删除事件delete_queryset和delete_model。这样我们就不需要处理像django.db.models.signals.pre_delete或django.db.models.signals.post_delete这样的信号。
这是完整的代码,
from django.contrib import admin
from . import models
class AdminInfo(admin.ModelAdmin):
model = models.AdminInfo
actions = ['delete_model']
def delete_queryset(self, request, queryset):
print('========================delete_queryset========================')
print(queryset)
"""
you can do anything here BEFORE deleting the object(s)
"""
queryset.delete()
"""
you can do anything here AFTER deleting the object(s)
"""
print('========================delete_queryset========================')
def delete_model(self, request, obj):
print('==========================delete_model==========================')
print(obj)
"""
you can do anything here BEFORE deleting the object
"""
obj.delete()
"""
you can do anything here AFTER deleting the object
"""
print('==========================delete_model==========================')
admin.site.register(models.AdminInfo, AdminInfo)
Run Code Online (Sandbox Code Playgroud)
Aid*_*wen 11
您使用自己的delete_model方法走在正确的轨道上.当django admin立即对多个对象执行操作时,它使用更新功能.但是,正如您在文档中看到的那样,这些操作仅在数据库级别使用SQL执行.
您需要在django admin 中将您的delete_model方法添加为自定义操作.
def delete_model(modeladmin, request, queryset):
for obj in queryset:
filename=obj.profile_name+".xml"
os.remove(os.path.join(obj.type,filename))
obj.delete()
Run Code Online (Sandbox Code Playgroud)
然后将您的功能添加到您的modeladmin -
class profilesAdmin(admin.ModelAdmin):
list_display = ["type","username","domain_name"]
actions = [delete_model]
Run Code Online (Sandbox Code Playgroud)
主要问题是Django管理员的批量删除使用SQL,而不是instance.delete(),如其他地方所述.对于仅限管理员的解决方案,以下解决方案保留了Django管理员的"你真的想删除这些"插页式广告.
最通用的解决方案是覆盖模型管理器返回的查询集以拦截删除.
from django.contrib.admin.actions import delete_selected
class BulkDeleteMixin(object):
class SafeDeleteQuerysetWrapper(object):
def __init__(self, wrapped_queryset):
self.wrapped_queryset = wrapped_queryset
def _safe_delete(self):
for obj in self.wrapped_queryset:
obj.delete()
def __getattr__(self, attr):
if attr == 'delete':
return self._safe_delete
else:
return getattr(self.wrapped_queryset, attr)
def __iter__(self):
for obj in self.wrapped_queryset:
yield obj
def __getitem__(self, index):
return self.wrapped_queryset[index]
def __len__(self):
return len(self.wrapped_queryset)
def get_actions(self, request):
actions = super(BulkDeleteMixin, self).get_actions(request)
actions['delete_selected'] = (BulkDeleteMixin.action_safe_bulk_delete, 'delete_selected', ugettext_lazy("Delete selected %(verbose_name_plural)s"))
return actions
def action_safe_bulk_delete(self, request, queryset):
wrapped_queryset = BulkDeleteMixin.SafeDeleteQuerysetWrapper(queryset)
return delete_selected(self, request, wrapped_queryset)
class SomeAdmin(BulkDeleteMixin, admin.ModelAdmin):
...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20404 次 |
| 最近记录: |