Модель Django: delete () не запущена

Вы можете сопоставить диск с помощью удаленного рабочего стола.

Параметры> Локальные ресурсы> Дополнительно

enter image description here [/g0]

34
задан Dominic Rodger 24 September 2009 в 14:17
поделиться

2 ответа

I think you're probably using the admin's bulk delete feature, and are running into the fact that the admin's bulk delete method doesn't call delete() (see the related ticket).

I've got round this in the past by writing a custom admin action for deleting models.

If you're not using the admin's bulk delete method (e.g. you're clicking the delete button on the object's edit page) then something else is going on.

See the warning here:

The “delete selected objects” action uses QuerySet.delete() for efficiency reasons, which has an important caveat: your model’s delete() method will not be called.

If you wish to override this behavior, simply write a custom action which accomplishes deletion in your preferred manner – for example, by calling Model.delete() for each of the selected items.

For more background on bulk deletion, see the documentation on object deletion.

My custom admin model looks like this:

from photoblog.models import PhotoBlogEntry
from django.contrib import admin    

class PhotoBlogEntryAdmin(admin.ModelAdmin):
    actions=['really_delete_selected']

    def get_actions(self, request):
        actions = super(PhotoBlogEntryAdmin, self).get_actions(request)
        del actions['delete_selected']
        return actions

    def really_delete_selected(self, request, queryset):
        for obj in queryset:
            obj.delete()

        if queryset.count() == 1:
            message_bit = "1 photoblog entry was"
        else:
            message_bit = "%s photoblog entries were" % queryset.count()
        self.message_user(request, "%s successfully deleted." % message_bit)
    really_delete_selected.short_description = "Delete selected entries"

admin.site.register(PhotoBlogEntry, PhotoBlogEntryAdmin)
72
ответ дан 27 November 2019 в 16:01
поделиться

Используя django v2.2.2, я решил эту проблему со следующим кодом

models.py

class MyModel(models.Model):
    file = models.FileField(upload_to=<path>)

    def save(self, *args, **kwargs):
        if self.pk is not None:
            old_file = MyModel.objects.get(pk=self.pk).file
            if old_file.path != self.file.path:
                self.file.storage.delete(old_file.path)

        return super(MyModel, self).save(*args, **kwargs)

    def delete(self, *args, **kwargs):
        ret = super(MyModel, self).delete(*args, **kwargs)
        self.file.storage.delete(self.file.path)
        return ret

admin.py

class MyModelAdmin(admin.ModelAdmin):

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

Для DefaultAdminSite, которым называют delete_queryset, если у пользователя есть корректные полномочия, единственная разница - то, что исходные вызовы функции queryset.delete(), который не инициировал метод модели delete. Это менее эффективно, так как больше не объемная операция, но она содержит файловую систему в чистоте =)

1
ответ дан 27 November 2019 в 16:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: