def init_request(self, object_id, *args, **kwargs): """ 初始化操作。根据传入的 ``object_id`` 取得要被删除的数据对象,而后进行权限判断 """ self.obj = self.get_object(unquote(object_id)) if not self.has_delete_permission(self.obj): raise PermissionDenied if self.obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(self.opts.verbose_name), 'key': escape(object_id) }) using = router.db_for_write(self.model) # 取得所用db # 生成 deleted_objects, 存有所有即将被删除的关联数据 if django_version > (2, 1): (self.deleted_objects, model_count, self.perms_needed, self.protected) = get_deleted_objects([self.obj], self.opts, self.admin_site) else: (self.deleted_objects, model_count, self.perms_needed, self.protected) = get_deleted_objects([self.obj], self.opts, self.request.user, self.admin_site, using)
def init_request(self, object_id, *args, **kwargs): "The 'delete' admin view for this model." self.obj = self.get_object(unquote(object_id)) if not self.has_delete_permission(self.obj): raise PermissionDenied if self.obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(self.opts.verbose_name), 'key': escape(object_id) }) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. if django_version > (2, 1): (self.deleted_objects, model_count, self.perms_needed, self.protected) = get_deleted_objects([self.obj], self.opts, self.admin_site) else: (self.deleted_objects, model_count, self.perms_needed, self.protected) = get_deleted_objects([self.obj], self.opts, self.request.user, self.admin_site, using)
def do_action(self, queryset): # Check that the user has delete permission for the actual model if not self.has_delete_permission(): raise PermissionDenied using = router.db_for_write(self.model) if django_version > (2, 0): setattr(self.admin_site._registry[self.model], 'has_delete_permission', self.has_delete_permission) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. if django_version > (2, 0): deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, self.opts, self.admin_site) else: deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, self.opts, self.user, self.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if self.request.POST.get('post'): if perms_needed: raise PermissionDenied self.delete_models(queryset) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_text(self.opts.verbose_name) else: objects_name = force_text(self.opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = self.get_context() context.update({ "title": title, "objects_name": objects_name, "deletable_objects": [deletable_objects], 'queryset': queryset, "perms_lacking": perms_needed, "protected": protected, "opts": self.opts, "app_label": self.app_label, 'action_checkbox_name': ACTION_CHECKBOX_NAME, }) # Display the confirmation page return TemplateResponse( self.request, self.delete_selected_confirmation_template or self.get_template_list('views/model_delete_selected_confirm.html'), context)
def delete_plugin(self, request, plugin_id): plugin = get_object_or_404( CMSPlugin.objects.select_related('placeholder'), pk=plugin_id) if not self.has_delete_plugin_permission(request, plugin): return HttpResponseForbidden( force_text( _("You do not have permission to delete this plugin"))) plugin_cms_class = plugin.get_plugin_class() plugin_class = plugin_cms_class.model opts = plugin_class._meta using = router.db_for_write(plugin_class) app_label = opts.app_label if DJANGO_1_7: deleted_objects, perms_needed, protected = get_deleted_objects( [plugin], opts, request.user, self.admin_site, using) else: deleted_objects, __, perms_needed, protected = get_deleted_objects( [plugin], opts, request.user, self.admin_site, using) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied( _("You do not have permission to delete this plugin")) obj_display = force_text(plugin) self.log_deletion(request, plugin, obj_display) plugin.delete() self.message_user( request, _('The %(name)s plugin "%(obj)s" was deleted successfully.') % { 'name': force_text(opts.verbose_name), 'obj': force_text(obj_display) }) self.post_delete_plugin(request, plugin) return HttpResponseRedirect( admin_reverse('index', current_app=self.admin_site.name)) plugin_name = force_text( plugin_pool.get_plugin(plugin.plugin_type).name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": plugin_name} else: title = _("Are you sure?") context = { "title": title, "object_name": plugin_name, "object": plugin, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, } return TemplateResponse( request, "admin/cms/page/plugin/delete_confirmation.html", context, current_app=self.admin_site.name)
def clear_placeholder(self, request, placeholder_id): placeholder = get_object_or_404(Placeholder, pk=placeholder_id) if not self.has_clear_placeholder_permission(request, placeholder): return HttpResponseForbidden( force_text( _("You do not have permission to clear this placeholder"))) language = request.GET.get('language', None) plugins = placeholder.get_plugins(language) opts = Placeholder._meta using = router.db_for_write(Placeholder) app_label = opts.app_label if DJANGO_1_7: deleted_objects, perms_needed, protected = get_deleted_objects( plugins, opts, request.user, self.admin_site, using) else: deleted_objects, __, perms_needed, protected = get_deleted_objects( plugins, opts, request.user, self.admin_site, using) obj_display = force_text(placeholder) if request.POST: # The user has already confirmed the deletion. if perms_needed: return HttpResponseForbidden( force_text( _("You do not have permission to clear this placeholder" ))) self.log_deletion(request, placeholder, obj_display) placeholder.clear(language) self.message_user( request, _('The placeholder "%(obj)s" was cleared successfully.') % {'obj': force_text(obj_display)}) self.post_clear_placeholder(request, placeholder) return HttpResponseRedirect( admin_reverse('index', current_app=self.admin_site.name)) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": obj_display} else: title = _("Are you sure?") context = { "title": title, "object_name": _("placeholder"), "object": placeholder, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, } return TemplateResponse( request, "admin/cms/page/plugin/delete_confirmation.html", context, current_app=self.admin_site.name)
def delete_plugin(self, request, plugin_id): plugin = get_object_or_404( CMSPlugin.objects.select_related('placeholder'), pk=plugin_id) if not self.has_delete_plugin_permission(request, plugin): return HttpResponseForbidden(force_text( _("You do not have permission to delete this plugin"))) plugin_cms_class = plugin.get_plugin_class() plugin_class = plugin_cms_class.model opts = plugin_class._meta using = router.db_for_write(plugin_class) app_label = opts.app_label if DJANGO_1_7: deleted_objects, perms_needed, protected = get_deleted_objects( [plugin], opts, request.user, self.admin_site, using) else: deleted_objects, __, perms_needed, protected = get_deleted_objects( [plugin], opts, request.user, self.admin_site, using) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied(_("You do not have permission to delete this plugin")) obj_display = force_text(plugin) self.log_deletion(request, plugin, obj_display) plugin.delete() self.message_user(request, _('The %(name)s plugin "%(obj)s" was deleted successfully.') % { 'name': force_text(opts.verbose_name), 'obj': force_text(obj_display)}) self.post_delete_plugin(request, plugin) return HttpResponseRedirect(admin_reverse('index', current_app=self.admin_site.name)) plugin_name = force_text(plugin_pool.get_plugin(plugin.plugin_type).name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": plugin_name} else: title = _("Are you sure?") context = { "title": title, "object_name": plugin_name, "object": plugin, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, } request.current_app = self.admin_site.name if DJANGO_1_7: return TemplateResponse( request, "admin/cms/page/plugin/delete_confirmation.html", context, current_app=self.admin_site.name ) else: return TemplateResponse( request, "admin/cms/page/plugin/delete_confirmation.html", context )
def do_action(self, queryset): # Check that the user has delete permission for the actual model if not self.has_delete_permission(): raise PermissionDenied # Populate deletable_objects, a data structure of all related objects that # will also be deleted. if django_version > (2, 1): deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, self.opts, self.admin_site) else: using = router.db_for_write(self.model) deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, self.opts, self.user, self.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if self.request.POST.get('post'): if perms_needed: raise PermissionDenied self.delete_models(queryset) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_text(self.opts.verbose_name) else: objects_name = force_text(self.opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = self.get_context() context.update({ "title": title, "objects_name": objects_name, "deletable_objects": [deletable_objects], 'queryset': queryset, "perms_lacking": perms_needed, "protected": protected, "opts": self.opts, "app_label": self.app_label, 'action_checkbox_name': ACTION_CHECKBOX_NAME, }) # Display the confirmation page return TemplateResponse(self.request, self.delete_selected_confirmation_template or self.get_template_list('views/model_delete_selected_confirm.html'), context)
def ajaxdelete_view(self, request, object_id): "The 'delete' admin view for this model." opts = self.model._meta app_label = opts.app_label obj = self.get_object(request, unquote(object_id)) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)} ) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, perms_needed, protected) = get_deleted_objects( [obj], opts, request.user, self.admin_site, using) if perms_needed: return PermissionDenied obj_display = force_text(obj) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) return HttpResponse('<html><body>OK</body></html>')
def ajaxdelete_view(self, request, object_id): "The 'delete' admin view for this model." opts = self.model._meta app_label = opts.app_label obj = self.get_object(request, unquote(object_id)) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id) }) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, perms_needed, protected) = get_deleted_objects([obj], opts, request.user, self.admin_site, using) if perms_needed: return PermissionDenied obj_display = force_text(obj) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) return HttpResponse('<html><body>OK</body></html>')
def do_action(self, queryset): # Check that the user has delete permission for the actual model if not self.has_delete_permission(): raise PermissionDenied using = router.db_for_write(self.model) if (self.model_name=='filetype' or self.model_name=='discipline' or self.model_name=='language' or self.model_name=='spacescope' or self.model_name=='format'): for obj in queryset: data = obj.filebaseinfo_set.all() if data: messages.info(self.request, (_(u"存在关联数据无法删除 %(name)s") % {"name": obj})) return redirect('.') # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, self.opts, self.user, self.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if self.request.POST.get('post'): if perms_needed: raise PermissionDenied self.delete_models(queryset) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_unicode(self.opts.verbose_name) else: objects_name = force_unicode(self.opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = self.get_context() context.update({ "title": title, "objects_name": objects_name, "deletable_objects": [deletable_objects], 'queryset': queryset, "perms_lacking": perms_needed, "protected": protected, "opts": self.opts, "app_label": self.app_label, 'action_checkbox_name': ACTION_CHECKBOX_NAME, }) # Display the confirmation page return TemplateResponse(self.request, self.delete_selected_confirmation_template or self.get_template_list('views/model_delete_selected_confirm.html'), context, current_app=self.admin_site.name)
def delete_forum(self, request, queryset): """ This method remove forum selected in the admin django. Can remove one o more records. """ if not self.has_delete_permission(request): raise PermissionDenied if request.POST.get("post"): for obj in queryset: idforum = obj.idforum # Remove permissions to moderators obj.remove_user_permissions_moderator() # Delete record models.Forum.objects.filter( idforum=idforum ).delete() n = queryset.count() self.message_user( request, _("Successfully deleted %(count)d record/s.") % { "count": n, }, messages.SUCCESS ) return None else: opts = self.model._meta if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) using = router.db_for_write(self.model) del_obj, model_c, perms_n, protected = get_deleted_objects( queryset, opts, request.user, self.admin_site, using ) context = { 'title': "", 'delete_topic': [queryset], 'ids': queryset.values_list("idforum"), 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'opts': opts, 'objects_name': objects_name, 'deletable_objects': [del_obj], 'action': 'delete_forum' } return TemplateResponse( request, 'musette/admin/confirm_delete.html', context )
def _folder_form_delete(self, request, obj): if not self.has_delete_permission(request, obj): raise PermissionDenied using = router.db_for_write(obj.__class__) # Populate deleted_objects, a data structure of all related objects # that will also be deleted. if django.VERSION < (2, 1): ( deleted_objects, model_count, perms_needed, protected, ) = get_deleted_objects( # noqa [obj], obj._meta, request.user, self.admin_site, using ) else: ( deleted_objects, model_count, perms_needed, protected, ) = self.get_deleted_objects( [obj], request ) # noqa if protected or perms_needed: self.message_user( request, _("Cannot delete %(name)s") % {"name": obj._meta.verbose_name}, messages.ERROR, ) elif len(deleted_objects) > 1: self.message_user( request, _("Cannot delete %(name)s because of related objects (%(related)s)") % { # noqa "name": obj._meta.verbose_name, "related": ", ".join( "%s %s" % (count, name) for name, count in model_count.items() ), }, messages.ERROR, ) else: obj.delete() self.message_user( request, _('The folder "%s" was deleted successfully.') % obj, messages.SUCCESS, ) return self.redirect_to_folder(request, obj.parent_id)
def delete(request, queryset): model = queryset.model opts = model._meta action = sys._getframe().f_code.co_name action_name = "删除" modeladmin = admin.site._registry.get(model) # queryset = queryset.filter(actived=False) if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, request, modeladmin.admin_site) if request.POST.get('post') and not protected: if perms_needed: raise PermissionDenied if queryset.count(): for obj in queryset: log_action( user_id=request.user.pk, content_type_id=get_content_type_for_model(obj, True).pk, object_id=obj.pk, action_flag="删除" ) if not SOFT_DELELE: queryset.delete() else: queryset.update(deleted=True, actived=False) return None if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) meta, menus = construct_model_meta(request, model, action_name) context = dict( objects_name=objects_name, deletable_objects=[deletable_objects], model_count=dict(model_count).items(), queryset=queryset, perms_lacking=perms_needed, protected=protected, opts=opts, meta=meta, action=action, action_name=action_name, menus=menus, ) request.current_app = modeladmin.admin_site.name return TemplateResponse(request, 'base/base_confirmation.html', context)
def clear_placeholder(self, request, placeholder_id): placeholder = get_object_or_404(Placeholder, pk=placeholder_id) if not self.has_clear_placeholder_permission(request, placeholder): return HttpResponseForbidden(force_text(_("You do not have permission to clear this placeholder"))) language = request.GET.get('language', None) plugins = placeholder.get_plugins(language) opts = Placeholder._meta using = router.db_for_write(Placeholder) app_label = opts.app_label if DJANGO_1_7: deleted_objects, perms_needed, protected = get_deleted_objects( plugins, opts, request.user, self.admin_site, using) else: deleted_objects, __, perms_needed, protected = get_deleted_objects( plugins, opts, request.user, self.admin_site, using) obj_display = force_text(placeholder) if request.POST: # The user has already confirmed the deletion. if perms_needed: return HttpResponseForbidden(force_text(_("You do not have permission to clear this placeholder"))) self.log_deletion(request, placeholder, obj_display) placeholder.clear(language) self.message_user(request, _('The placeholder "%(obj)s" was cleared successfully.') % { 'obj': force_text(obj_display)}) self.post_clear_placeholder(request, placeholder) return HttpResponseRedirect(admin_reverse('index', current_app=self.admin_site.name)) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": obj_display} else: title = _("Are you sure?") context = { "title": title, "object_name": _("placeholder"), "object": placeholder, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, } return TemplateResponse(request, "admin/cms/page/plugin/delete_confirmation.html", context, current_app=self.admin_site.name)
def init_request(self, object_id, *args, **kwargs): "The 'delete' admin view for this model." self.obj = self.get_object(unquote(object_id)) if not self.has_delete_permission(self.obj): raise PermissionDenied if self.obj is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(self.opts.verbose_name), 'key': escape(object_id)}) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. if django_version > (2, 1): (self.deleted_objects, model_count, self.perms_needed, self.protected) = get_deleted_objects( [self.obj], self.opts, self.admin_site) else: (self.deleted_objects, model_count, self.perms_needed, self.protected) = get_deleted_objects( [self.obj], self.opts, self.request.user, self.admin_site, using)
def get_rdepends(self, object): if not hasattr(object, '_rdepends'): if django_version >= (1, 1, 4): # == GETTING TO_BE_DELETED OBJECTS THE DJANGO 1.1.4+ WAY == class AnonymousUser: is_staff = is_superuser = False def has_perm(self, perm): return False # Hacks to force has_admin=False class AdminSite: name = 'irrelevant' _registry = {} if django_version >= (1, 3): using = 'default' retval = get_deleted_objects((object, ), object._meta, AnonymousUser(), AdminSite(), using) if django_version >= (1, 8): (dependent_objects, _, perms_needed, protected) = retval else: (dependent_objects, perms_needed, protected) = retval else: (dependent_objects, perms_needed) = \ get_deleted_objects((object,), object._meta, AnonymousUser(), AdminSite()) object._old_rdepends = False else: # == GETTING TO_BE_DELETED OBJECTS THE DJANGO 1.1.1- WAY == dependent_objects = [unicode(object), []] perms_needed = set() get_deleted_objects(dependent_objects, perms_needed, None, object, object._meta, 1, admin.site) object._old_rdepends = True object._rdepends = dependent_objects return object._rdepends
def delete_selected_action(self, model_admin, request, qs): objects = UsersTasksValidationAdmin.QSList(qs) if request.POST.get('post'): deletable_objects, model_count, perms_needed, protected = get_deleted_objects( objects, request, model_admin.admin_site) if not protected: res = delete_selected(model_admin, request, objects) for obj in objects: self.on_object_deleted(obj) return res response = delete_selected(model_admin, request, objects) context = response.context_data context['running_tasks'] = self.get_user_task_names() or None return TemplateResponse(request, model_admin.delete_selected_confirmation_template, context)
def delete_topic(self, request, queryset): ''' This method remove topic's selected in the admin django. Can remove one o more records. ''' if not self.has_delete_permission(request): raise PermissionDenied if request.POST.get("post"): for obj in queryset: idtopic = obj.idtopic #Remove folder attachment remove_folder_attachment(idtopic) # Delete record Topic.objects.filter(idtopic=idtopic).delete() n = queryset.count() self.message_user(request, _("Successfully deleted %(count)d record/s.") % { "count": n, }, messages.SUCCESS) return None else: opts = self.model._meta if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) using = router.db_for_write(self.model) deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, self.admin_site, using) context = { 'title': "", 'delete_topic': [queryset], 'ids': queryset.values_list("idtopic"), 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'opts': opts, 'objects_name': objects_name, 'deletable_objects': [deletable_objects], } return TemplateResponse( request, 'forum/admin/confirm_delete.html', context, current_app=self.admin_site.name )
def has_delete_permission(self, request, obj=None): if obj: # Ici on récupere brutalement les objets suscebtibles d'etre supprimés # si on aurai supprimé l'instance courante opts = self.model._meta using = router.db_for_write(self.model) (deleted_objects, model_count, perms_needed, protected) = get_deleted_objects([obj], opts, request.user, self.admin_site, using) # Si on ne retrouve uniquement que l'instance courante parmis # les objets a supprimés alors on autorise. if len(deleted_objects) == 1: return True return False
def _get_to_be_deleted_objects(self, menu_item, request): def _get_related_objects(menu_item): # Since we are using treebeard, the default 'to_be_deleted' functionality from django # does not work, therefore we must construct the list here and # pass it to the delete confirmation. yield menu_item for child_item in menu_item.get_children(): yield child_item to_be_deleted = list(_get_related_objects(menu_item)) get_deleted_objects_additional_context = {"request": request} (deleted_objects, model_count, perms_needed, protected) = get_deleted_objects( to_be_deleted, admin_site=self.admin_site, **get_deleted_objects_additional_context) return deleted_objects
def get_deleted_objects(self, test_sessions, request): """ Method getting the list of objects related to test sessions that will be deleted If we find related snapshots that are reference for other snapshot, add an item in object list. This item (__delete_reference_snapshots__) will be interpreted by custom admin templates to display a warning """ deletable_objects, model_count, perms_needed, protected = get_deleted_objects( test_sessions, request, self.admin_site) # Search all snapshots related to test sessions to delete and check if they are reference for others snapshots_to_delete = Snapshot.objects.filter( stepResult__testCase__session__in=test_sessions) snapshots_reference_for_other = Snapshot.objects.filter( refSnapshot__in=snapshots_to_delete) if snapshots_reference_for_other: deletable_objects.append('__delete_reference_snapshots__') return deletable_objects, model_count, perms_needed, protected
def delete_selected(modeladmin, request, queryset): opts = modeladmin.model._meta if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) deletable_objects, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, modeladmin.admin_site, using) n = queryset.count() if n: for obj in queryset: obj_display = force_text(obj) modeladmin.log_deletion(request, obj, obj_display) queryset.delete() modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % { "count": n, "items": model_ngettext(modeladmin.opts, n) }, messages.SUCCESS) return redirect('.')
def delete_selected(modeladmin, request, queryset): """ Default action which deletes the selected objects. This action first displays a confirmation page which shows all the deletable objects, or, if the user has no permission one of the related childs (foreignkeys), a "permission denied" message. Next, it deletes all selected objects and redirects back to the change list. """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, modeladmin.admin_site, using)
def delete_selected(modeladmin, request, queryset): opts = modeladmin.model._meta if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, modeladmin.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = queryset.count() if n: for obj in queryset: obj_display = force_text(obj) modeladmin.log_deletion(request, obj, obj_display) remove_program_elasticsearch(program_id=obj.id) queryset.delete() 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 else: return django_delete_selected(modeladmin, request, queryset)
def delete_view(self, request, object_id, extra_context=None): """ This method overrides the 'delete' admin view. Changes include handling exceptions raised while deleting a model and displaying the exception message to the user in a readable format instead of showing the exception page to the user """ opts = self.model._meta app_label = opts.app_label to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField( "The field %s cannot be referenced." % to_field) obj = self.get_object(request, unquote(object_id), to_field) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id) }) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, model_count, perms_needed, protected) = get_deleted_objects([obj], opts, request.user, self.admin_site, using) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = force_text(obj) attr = str(to_field) if to_field else opts.pk.attname obj_id = obj.serializable_value(attr) # start: base changes try: self.delete_model(request, obj) except Exception as e: return self.response_delete(request, obj_display, obj_id, msg=e.message, msg_type=messages.ERROR) self.log_deletion(request, obj, obj_display) # end: base changes return self.response_delete(request, obj_display, obj_id) object_name = force_text(opts.verbose_name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = dict( self.admin_site.each_context(request), title=title, object_name=object_name, object=obj, deleted_objects=deleted_objects, model_count=dict(model_count).items(), perms_lacking=perms_needed, protected=protected, opts=opts, app_label=app_label, preserved_filters=self.get_preserved_filters(request), is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=to_field, ) context.update(extra_context or {}) return self.render_delete_form(request, context)
def delete_selected(modeladmin, request, queryset): """ This is a fork of django.contrib.admin.actions.delete_selected But this calls object.delete() instead of queryset.delete() """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, modeladmin.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = queryset.count() if n: for obj in queryset: obj_display = force_text(obj) modeladmin.log_deletion(request, obj, obj_display) obj.delete() 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 if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = { "title": title, "objects_name": objects_name, "deletable_objects": [deletable_objects], 'queryset': queryset, "perms_lacking": perms_needed, "protected": protected, "opts": opts, 'action_checkbox_name': helpers.ACTION_CHECKBOX_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, current_app=modeladmin.admin_site.name)
def delete_related_objects(modeladmin, request, queryset): """ Action that deletes related objects for the selected items. This action first displays a confirmation page whichs shows all the deleteable objects, or, if the user has no permission one of the related childs (foreignkeys), a "permission denied" message. Next, it deletes all related objects and redirects back to the change list. """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) first_level_related_objects = [] collector = NestedObjects(using=using) collector.collect(queryset) for base_object_or_related_list in collector.nested(): if type(base_object_or_related_list) is not list: # If it's not a list, it's a base object. Skip it. continue for obj in base_object_or_related_list: if type(obj) is list: # A list here contains related objects for the previous # element. We can skip it since delete() on the first # level of related objects will cascade. continue elif not isinstance(obj, _ReadOnlyModel): first_level_related_objects.append(obj) # Populate deletable_objects, a data structure of (string representations # of) all related objects that will also be deleted. deletable_objects, model_count, perms_needed, protected = get_deleted_objects( first_level_related_objects, opts, request.user, modeladmin.admin_site, using ) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = 0 with transaction.atomic(using): for obj in first_level_related_objects: obj_display = force_text(obj) modeladmin.log_deletion(request, obj, obj_display) obj.delete() n += 1 modeladmin.message_user( request, _("Successfully deleted %(count)d related objects.") % { "count": n, "items": model_ngettext(modeladmin.opts, n)}, messages.SUCCESS ) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = dict( modeladmin.admin_site.each_context(request), title=title, objects_name=objects_name, deletable_objects=[deletable_objects], model_count=dict(model_count).items(), queryset=queryset, perms_lacking=perms_needed, protected=protected, opts=opts, action_checkbox_name=helpers.ACTION_CHECKBOX_NAME, ) request.current_app = modeladmin.admin_site.name # Display the confirmation page return TemplateResponse( request, "delete_related_for_selected_confirmation.html", context, current_app=modeladmin.admin_site.name)
def delete_translation(self, request, object_id, language_code): """ The 'delete translation' admin view for this model. """ opts = self.model._meta root_model = self.model._parler_meta.root_model # Get object and translation shared_obj = self.get_object(request, unquote(object_id)) if shared_obj is None: raise Http404 shared_obj.set_current_language(language_code) try: translation = root_model.objects.get(master=shared_obj, language_code=language_code) except root_model.DoesNotExist: raise Http404 if not self.has_delete_permission(request, translation): raise PermissionDenied if len(self.get_available_languages(shared_obj)) <= 1: return self.deletion_not_allowed(request, translation, language_code) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. using = router.db_for_write(root_model) # NOTE: all same DB for now. lang = get_language_title(language_code) # There are potentially multiple objects to delete; # the translation object at the base level, # and additional objects that can be added by inherited models. deleted_objects = [] perms_needed = False protected = [] # Extend deleted objects with the inlines. for qs in self.get_translation_objects(request, translation.language_code, obj=shared_obj, inlines=self.delete_inline_translations): if isinstance(qs, (list, tuple)): qs_opts = qs[0]._meta else: qs_opts = qs.model._meta deleted_result = get_deleted_objects(qs, qs_opts, request.user, self.admin_site, using) if django.VERSION >= (1, 8): (del2, model_counts, perms2, protected2) = deleted_result else: (del2, perms2, protected2) = deleted_result deleted_objects += del2 perms_needed = perms_needed or perms2 protected += protected2 if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = _('{0} translation of {1}').format(lang, force_text(translation)) # in hvad: (translation.master) self.log_deletion(request, translation, obj_display) self.delete_model_translation(request, translation) self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % dict( name=force_text(opts.verbose_name), obj=force_text(obj_display) )) if self.has_change_permission(request, None): info = _get_model_meta(opts) return HttpResponseRedirect(reverse('admin:{0}_{1}_change'.format(*info), args=(object_id,), current_app=self.admin_site.name)) else: return HttpResponseRedirect(reverse('admin:index', current_app=self.admin_site.name)) object_name = _('{0} Translation').format(force_text(opts.verbose_name)) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = { "title": title, "object_name": object_name, "object": translation, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": opts.app_label, } return render(request, self.delete_confirmation_template or [ "admin/%s/%s/delete_confirmation.html" % (opts.app_label, opts.object_name.lower()), "admin/%s/delete_confirmation.html" % opts.app_label, "admin/delete_confirmation.html" ], context)
def delete_view(self, request, object_id, extra_context=None): """ The 'delete' admin view for this model. This follows closely the base implementation from Django 1.7's django.contrib.admin.options.ModelAdmin, with the explicitly marked modifications. """ opts = self.model._meta app_label = opts.app_label obj = self.get_object(request, unquote(object_id)) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: return HttpResponseNotFound(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_unicode(opts.verbose_name), 'key': escape(object_id)}) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, perms_needed, protected) = get_deleted_objects( [obj], opts, request.user, self.admin_site, using) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = force_unicode(obj) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) #### Change starts here #### if not '_popup' in request.REQUEST: self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)}) return self.response_delete(request) #### Change ends here #### object_name = force_unicode(opts.verbose_name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = { "title": title, "object_name": object_name, "object": obj, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "root_path": self.admin_site.site_url, "app_label": app_label, } context.update(extra_context or {}) context_instance = template.RequestContext(request, current_app=self.admin_site.name) return render_to_response(self.delete_confirmation_template or [ "admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/delete_confirmation.html" % app_label, "admin/delete_confirmation.html" ], context, context_instance=context_instance)
def delete_plugin(self, request, plugin_id): plugin = self._get_plugin_from_id(plugin_id) if not self.has_delete_plugin_permission(request, plugin): return HttpResponseForbidden(force_text( _("You do not have permission to delete this plugin"))) opts = plugin._meta using = router.db_for_write(opts.model) deleted_objects, __, perms_needed, protected = get_deleted_objects( [plugin], opts, request.user, self.admin_site, using) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied(_("You do not have permission to delete this plugin")) obj_display = force_text(plugin) placeholder = plugin.placeholder plugin_tree_order = placeholder.get_plugin_tree_order( language=plugin.language, parent_id=plugin.parent_id, ) operation_token = self._send_pre_placeholder_operation( request, operation=operations.DELETE_PLUGIN, plugin=plugin, placeholder=placeholder, tree_order=plugin_tree_order, ) plugin.delete() self.log_deletion(request, plugin, obj_display) self.message_user(request, _('The %(name)s plugin "%(obj)s" was deleted successfully.') % { 'name': force_text(opts.verbose_name), 'obj': force_text(obj_display)}) # Avoid query by removing the plugin being deleted # from the tree order list new_plugin_tree_order = list(plugin_tree_order) new_plugin_tree_order.remove(plugin.pk) self._send_post_placeholder_operation( request, operation=operations.DELETE_PLUGIN, token=operation_token, plugin=plugin, placeholder=placeholder, tree_order=new_plugin_tree_order, ) return HttpResponseRedirect(admin_reverse('index', current_app=self.admin_site.name)) plugin_name = force_text(plugin.get_plugin_class().name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": plugin_name} else: title = _("Are you sure?") context = { "title": title, "object_name": plugin_name, "object": plugin, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": opts.app_label, } request.current_app = self.admin_site.name return TemplateResponse( request, "admin/cms/page/plugin/delete_confirmation.html", context )
def delete_translation(self, request, object_id, language_code): """ The 'delete translation' admin view for this model. """ opts = self.model._meta root_model = self.model._parler_meta.root_model # Get object and translation shared_obj = self.get_object(request, unquote(object_id)) if shared_obj is None: raise Http404 shared_obj.set_current_language(language_code) try: translation = root_model.objects.get(master=shared_obj, language_code=language_code) except root_model.DoesNotExist: raise Http404 if not self.has_delete_permission(request, translation): raise PermissionDenied if len(self.get_available_languages(shared_obj)) <= 1: return self.deletion_not_allowed(request, translation, language_code) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. using = router.db_for_write(root_model) # NOTE: all same DB for now. lang = get_language_title(language_code) # There are potentially multiple objects to delete; # the translation object at the base level, # and additional objects that can be added by inherited models. deleted_objects = [] perms_needed = False protected = [] # Extend deleted objects with the inlines. for qs in self.get_translation_objects( request, translation.language_code, obj=shared_obj, inlines=self.delete_inline_translations, ): if isinstance(qs, (list, tuple)): qs_opts = qs[0]._meta else: qs_opts = qs.model._meta if django.VERSION >= (2, 1): deleted_result = get_deleted_objects(qs, request, self.admin_site) else: deleted_result = get_deleted_objects(qs, qs_opts, request.user, self.admin_site, using) (del2, model_counts, perms2, protected2) = deleted_result deleted_objects += del2 perms_needed = perms_needed or perms2 protected += protected2 if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = _("{0} translation of {1}").format( lang, force_str(translation)) # in hvad: (translation.master) self.log_deletion(request, translation, obj_display) self.delete_model_translation(request, translation) self.message_user( request, _('The %(name)s "%(obj)s" was deleted successfully.') % dict(name=force_str(opts.verbose_name), obj=force_str(obj_display)), ) if self.has_change_permission(request, None): info = opts.app_label, opts.model_name return HttpResponseRedirect( reverse( "admin:{}_{}_change".format(*info), args=(object_id, ), current_app=self.admin_site.name, )) else: return HttpResponseRedirect( reverse("admin:index", current_app=self.admin_site.name)) object_name = _("{0} Translation").format(force_str(opts.verbose_name)) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = { "title": title, "object_name": object_name, "object": translation, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": opts.app_label, } # Small hack for django-polymorphic-tree. # This makes sure the breadcrumb renders correctly, # and avoids errors when the child model is not registered in the admin. if hasattr(self, "base_model"): context.update({ "base_opts": self.base_model._meta, }) return render( request, self.delete_confirmation_template or [ f"admin/{opts.app_label}/{opts.object_name.lower()}/delete_confirmation.html", "admin/%s/delete_confirmation.html" % opts.app_label, "admin/delete_confirmation.html", ], context, )
def delete_selected(modeladmin, request, queryset): """ The out-of-box Django delete never calls Submission.delete(), so this is a mostly redundant lift-and-hack to ensure that happens. This is important because Submission.delete() also cleans up its uploaded files. See also: https://docs.djangoproject.com/en/dev/ref/contrib/admin/actions/ """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, modeladmin.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = queryset.count() if n: for obj in queryset: obj_display = force_unicode(obj) modeladmin.log_deletion(request, obj, obj_display) obj.delete() modeladmin.message_user( request, _("Deleted and uploaded files for %(item)s") % { "item": obj_display }) modeladmin.message_user( request, _("Successfully deleted %(count)d %(items)s.") % { "count": n, "items": model_ngettext(modeladmin.opts, n) }) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_unicode(opts.verbose_name) else: objects_name = force_unicode(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = { "title": title, "object_name": objects_name, "deletable_objects": [deletable_objects], "queryset": queryset, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, "action_checkbox_name": helpers.ACTION_CHECKBOX_NAME, } # Display the confirmation page return TemplateResponse(request, modeladmin.delete_selected_confirmation_template or [ "admin/%s/%s/delete_selected_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/delete_selected_confirmation.html" % app_label, "admin/delete_selected_confirmation.html" ], context, current_app=modeladmin.admin_site.name)
def delete_view(self, request, object_id, extra_context=None): "The 'delete' admin view for this model." opts = self.model._meta app_label = opts.app_label obj = self.get_object(request, unquote(object_id)) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)}) # frePPLe specific selection of the database using = request.database # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, perms_needed, protected) = get_deleted_objects( [obj], opts, request.user, self.admin_site, using) # Update the links to the related objects. A bit of a hack... if request.prefix: def replace_url(a): if isinstance(a, list): return [ replace_url(i) for i in a ] else: return mark_safe(a.replace('href="', 'href="%s' % request.prefix)) deleted_objects = [ replace_url(i) for i in deleted_objects ] protected = [ replace_url(i) for i in protected ] if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = force_text(obj) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_text(opts.verbose_name), 'obj': force_text(obj_display)}) # Delete this entity page from the crumbs del request.session['crumbs'][request.prefix][-1] # Redirect to previous url return HttpResponseRedirect("%s%s" % (request.prefix, request.session['crumbs'][request.prefix][-1][2])) object_name = force_text(opts.verbose_name) context = { "title": capfirst(object_name + ' ' + unquote(object_id)), "object_name": object_name, "object": obj, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, } context.update(extra_context or {}) return TemplateResponse(request, self.delete_confirmation_template or [ "admin/%s/%s/delete_confirmation.html" % (app_label, opts.model_name), "admin/%s/delete_confirmation.html" % app_label, "admin/delete_confirmation.html" ], context, current_app=self.admin_site.name)
def delete_translation(self, request, object_id, language_code): "The 'delete translation' admin view for this model." opts = self.model._meta app_label = opts.app_label translations_model = opts.translations_model try: obj = translations_model.objects.select_related('master').get( master__pk=unquote(object_id), language_code=language_code) except translations_model.DoesNotExist: raise Http404 if not self.has_delete_permission(request, obj): raise PermissionDenied if len(obj.master.get_available_languages()) <= 1: return self.deletion_not_allowed(request, obj, language_code) using = router.db_for_write(translations_model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. protected = False deleted_objects, model_count, perms_needed, protected = get_deleted_objects( [obj], translations_model._meta, request.user, self.admin_site, using) lang = get_language_info(language_code)['name_local'] if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = u'%s translation of %s' % (force_text(lang), force_text(obj.master)) self.log_deletion(request, obj, obj_display) self.delete_model_translation(request, obj) self.message_user(request, _(u'The %(name)s "%(obj)s" was deleted successfully.') % { 'name': force_text(opts.verbose_name), 'obj': force_text(obj_display) } ) if not self.has_change_permission(request, None): return HttpResponseRedirect(self.reverse('admin:index')) return HttpResponseRedirect(self.reverse('admin:%s_%s_changelist' % (opts.app_label, opts.model_name))) object_name = _(u'%s Translation') % force_text(opts.verbose_name) if perms_needed or protected: title = _(u"Cannot delete %(name)s") % {"name": object_name} else: title = _(u"Are you sure?") return render( request, self.delete_confirmation_template or ( "admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/delete_confirmation.html" % app_label, "admin/delete_confirmation.html" ), { "title": title, "object_name": object_name, "object": obj, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, }, )
def _delete_view(self, request, object_id, extra_context): opts = self.model._meta app_label = opts.app_label to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField( "The field %s cannot be referenced." % to_field) obj = self.get_object(request, unquote(object_id), to_field) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: return self._get_obj_does_not_exist_redirect( request, opts, object_id) using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, model_count, perms_needed, protected) = get_deleted_objects([obj], opts, request.user, self.admin_site, using) if request.POST and not protected: # The user has confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = force_text(obj) attr = str(to_field) if to_field else opts.pk.attname course_id = obj.course.id obj_id = obj.serializable_value(attr) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) return self.response_delete(request, obj_display, obj_id, course_id) object_name = force_text(opts.verbose_name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = dict( self.admin_site.each_context(request), title=title, object_name=object_name, object=obj, deleted_objects=deleted_objects, model_count=dict(model_count).items(), perms_lacking=perms_needed, protected=protected, opts=opts, app_label=app_label, preserved_filters=self.get_preserved_filters(request), is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=to_field, ) context.update(extra_context or {}) return self.render_delete_form(request, context)
def soft_delete_selected(modeladmin, request, queryset): """ Replace the default delete_selected action so we can soft delete objects by using obj.delete() instead of queryset.delete(). Default action which deletes the selected objects. This action first displays a confirmation page whichs shows all the deleteable objects, or, if the user has no permission one of the related childs (foreignkeys), a "permission denied" message. Next, it soft deletes all selected objects and redirects back to the change list. """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, count, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, modeladmin.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = queryset.count() if n: for obj in queryset: obj_display = force_unicode(obj) modeladmin.log_deletion(request, obj, obj_display) # Delete the object with it's own method in case the # object has a custom delete method. obj.delete() modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % { "count": n, "items": model_ngettext(modeladmin.opts, n) }) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_unicode(opts.verbose_name) else: objects_name = force_unicode(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = { "title": title, "objects_name": objects_name, "deletable_objects": [deletable_objects], 'queryset': queryset, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, } # Display the confirmation page return TemplateResponse(request, [ "admin/%s/%s/soft_delete_selected_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/soft_delete_selected_confirmation.html" % app_label, "admin/soft_delete_selected_confirmation.html" ], context, current_app=modeladmin.admin_site.name)
def soft_delete_selected(modeladmin, request, queryset): """ Replace the default delete_selected action so we can soft delete objects by using obj.delete() instead of queryset.delete(). Default action which deletes the selected objects. This action first displays a confirmation page whichs shows all the deleteable objects, or, if the user has no permission one of the related childs (foreignkeys), a "permission denied" message. Next, it soft deletes all selected objects and redirects back to the change list. """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, count, perms_needed, protected = get_deleted_objects( queryset, request, modeladmin.admin_site, ) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = queryset.count() if n: for obj in queryset: obj_display = force_str(obj) modeladmin.log_deletion(request, obj, obj_display) # Delete the object with it's own method in case the # object has a custom delete method. obj.delete() modeladmin.message_user( request, _("Successfully deleted %(count)d %(items)s.") % { "count": n, "items": model_ngettext(modeladmin.opts, n) }) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_str(opts.verbose_name) else: objects_name = force_str(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = { "title": title, "objects_name": objects_name, "deletable_objects": [deletable_objects], 'queryset': queryset, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, } # Display the confirmation page request.current_app = modeladmin.admin_site.name return TemplateResponse( request=request, template=[ "admin/%s/%s/soft_delete_selected_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/soft_delete_selected_confirmation.html" % app_label, "admin/soft_delete_selected_confirmation.html" ], context=context)
def delete_related_objects(modeladmin, request, queryset): """ Action that deletes related objects for the selected items. This action first displays a confirmation page whichs shows all the deleteable objects, or, if the user has no permission one of the related childs (foreignkeys), a "permission denied" message. Next, it deletes all related objects and redirects back to the change list. The code is mostly copied from django/contrib/admin/actions.py """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) first_level_related_objects = [] collector = NestedObjects(using=using) collector.collect(queryset) for base_object_or_related_list in collector.nested(): if type(base_object_or_related_list) is not list: # If it's not a list, it's a base object. Skip it. continue for obj in base_object_or_related_list: if type(obj) is list: # A list here contains related objects for the previous # element. We can skip it since delete() on the first # level of related objects will cascade. continue elif not isinstance(obj, _ShadowModel): first_level_related_objects.append(obj) # Populate deletable_objects, a data structure of (string representations # of) all related objects that will also be deleted. deletable_objects, model_count, perms_needed, protected = get_deleted_objects( first_level_related_objects, opts, request.user, modeladmin.admin_site, using ) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = 0 with transaction.atomic(using): for obj in first_level_related_objects: obj_display = force_text(obj) modeladmin.log_deletion(request, obj, obj_display) obj.delete() n += 1 modeladmin.message_user( request, _("Successfully deleted %(count)d related objects.") % { "count": n, "items": model_ngettext(modeladmin.opts, n)}, messages.SUCCESS ) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = dict( modeladmin.admin_site.each_context(request), title=title, objects_name=objects_name, deletable_objects=[deletable_objects], model_count=dict(model_count).items(), queryset=queryset, perms_lacking=perms_needed, protected=protected, opts=opts, action_checkbox_name=helpers.ACTION_CHECKBOX_NAME, ) request.current_app = modeladmin.admin_site.name # Display the confirmation page return TemplateResponse( request, "delete_related_for_selected_confirmation.html", context, current_app=modeladmin.admin_site.name)
def delete_topic(self, request, queryset): ''' This method remove forum selected in the admin django. Can remove one o more records. ''' if not self.has_delete_permission(request): raise PermissionDenied if request.POST.get("post"): for obj in queryset: idforum = obj.idforum if not obj.moderators.is_superuser: if obj.moderators: # Return forums that moderating one moderator tot_forum_moderator = Forum.objects.filter( moderators=obj.moderators).count() # Only remove permissions if is moderator one forum if tot_forum_moderator <= 1: try: u = User.objects.get(username=obj.moderators) u.user_permissions.clear() except Exception: pass # Delete record Forum.objects.filter(idforum=idforum).delete() n = queryset.count() self.message_user( request, _("Successfully deleted %(count)d record/s.") % { "count": n, }, messages.SUCCESS) return None else: opts = self.model._meta if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) using = router.db_for_write(self.model) del_obj, model_c, perms_n, protected = get_deleted_objects( queryset, opts, request.user, self.admin_site, using) context = { 'title': "", 'delete_topic': [queryset], 'ids': queryset.values_list("idforum"), 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'opts': opts, 'objects_name': objects_name, 'deletable_objects': [del_obj], } return TemplateResponse(request, 'musette/admin/confirm_delete.html', context, current_app=self.admin_site.name)
def delete_view(self, request, object_id, extra_context=None): "The 'delete' admin view for this model." opts = self.model._meta app_label = opts.app_label to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field) obj = self.get_object(request, unquote(object_id), to_field) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)} ) from django.db import router using = router.db_for_write(self.model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, model_count, perms_needed, protected) = get_deleted_objects( [obj], opts, request.user, self.admin_site, using) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = force_text(obj) attr = str(to_field) if to_field else opts.pk.attname obj_id = obj.serializable_value(attr) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) return self.response_delete(request, obj_display, obj_id) object_name = force_text(opts.verbose_name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = dict( self.admin_site.each_context(request), title=title, object_name=object_name, object=obj, deleted_objects=deleted_objects, model_count=dict(model_count).items(), perms_lacking=perms_needed, protected=protected, opts=opts, app_label=app_label, preserved_filters=self.get_preserved_filters(request), is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=to_field, ) context.update(extra_context or {}) return self.render_delete_form(request, context)
from django.core.exceptions import PermissionDenied
def delete_view(self, request, object_id, extra_context=None): """ The 'delete' admin view for this model. """ opts = self.model._meta app_label = opts.app_label to_field = request.POST.get('_to_field', request.GET.get('_to_field')) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field) obj = self.get_object(request, unquote(object_id)) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: # Translators: Translation included with Django raise Http404(_('%(name)s object with primary key %(key)r does not exist.') % {'name': force_text(opts.verbose_name), 'key': escape(object_id)}) # frePPLe specific selection of the database using = request.database # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, model_count, perms_needed, protected) = get_deleted_objects( [obj], opts, request.user, self.admin_site, using ) # Update the links to the related objects. frePPLe specific. if request.prefix: def replace_url(a): if isinstance(a, list): return [ replace_url(i) for i in a ] else: return mark_safe(a.replace('href="', 'href="%s' % request.prefix)) deleted_objects = [ replace_url(i) for i in deleted_objects ] protected = [ replace_url(i) for i in protected ] if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = force_text(obj) attr = str(to_field) if to_field else opts.pk.attname obj_id = obj.serializable_value(attr) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) return self.response_delete(request, obj_display, obj_id) object_name = force_text(opts.verbose_name) context = dict( self.admin_site.each_context(request), title=capfirst(object_name + ' ' + unquote(object_id)), object_name=object_name, object=obj, deleted_objects=deleted_objects, model_count=dict(model_count).items(), perms_lacking=perms_needed, protected=protected, opts=opts, app_label=app_label, preserved_filters=self.get_preserved_filters(request), is_popup=('_popup' in request.POST or '_popup' in request.GET), to_field=to_field, ) context.update(extra_context or {}) return self.render_delete_form(request, context)
def clear_placeholder(self, request, placeholder_id): placeholder = get_object_or_404(Placeholder, pk=placeholder_id) language = request.GET.get('language') if placeholder.pk == request.toolbar.clipboard.pk: # User is clearing the clipboard, no need for permission # checks here as the clipboard is unique per user. # There could be a case where a plugin has relationship to # an object the user does not have permission to delete. placeholder.clear(language) return HttpResponseRedirect(admin_reverse('index', current_app=self.admin_site.name)) if not self.has_clear_placeholder_permission(request, placeholder, language): return HttpResponseForbidden(force_text(_("You do not have permission to clear this placeholder"))) opts = Placeholder._meta using = router.db_for_write(Placeholder) plugins = placeholder.get_plugins_list(language) deleted_objects, __, perms_needed, protected = get_deleted_objects( plugins, opts, request.user, self.admin_site, using) obj_display = force_text(placeholder) if request.POST: # The user has already confirmed the deletion. if perms_needed: return HttpResponseForbidden(force_text(_("You do not have permission to clear this placeholder"))) operation_token = self._send_pre_placeholder_operation( request, operation=operations.CLEAR_PLACEHOLDER, plugins=plugins, placeholder=placeholder, ) placeholder.clear(language) placeholder.mark_as_dirty(language, clear_cache=True) self.log_deletion(request, placeholder, obj_display) self.message_user(request, _('The placeholder "%(obj)s" was cleared successfully.') % { 'obj': obj_display}) self._send_post_placeholder_operation( request, operation=operations.CLEAR_PLACEHOLDER, token=operation_token, plugins=plugins, placeholder=placeholder, ) return HttpResponseRedirect(admin_reverse('index', current_app=self.admin_site.name)) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": obj_display} else: title = _("Are you sure?") context = { "title": title, "object_name": _("placeholder"), "object": placeholder, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": opts.app_label, } request.current_app = self.admin_site.name return TemplateResponse(request, "admin/cms/page/plugin/delete_confirmation.html", context)
def delete_translation(self, request, object_id, language_code): "The 'delete translation' admin view for this model." opts = self.model._meta app_label = opts.app_label translations_model = opts.translations_model try: obj = translations_model.objects.select_related('master').get( master__pk=unquote(object_id), language_code=language_code) except translations_model.DoesNotExist: raise Http404 if not self.has_delete_permission(request, obj): raise PermissionDenied if len(obj.master.get_available_languages()) <= 1: return self.deletion_not_allowed(request, obj, language_code) using = router.db_for_write(translations_model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. protected = False deleted_objects, model_count, perms_needed, protected = get_deleted_objects( [obj], translations_model._meta, request.user, self.admin_site, using) lang = get_language_info(language_code)['name_local'] if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = u'%s translation of %s' % (force_text(lang), force_text(obj.master)) self.log_deletion(request, obj, obj_display) self.delete_model_translation(request, obj) self.message_user( request, _(u'The %(name)s "%(obj)s" was deleted successfully.') % { 'name': force_text(opts.verbose_name), 'obj': force_text(obj_display) }) if not self.has_change_permission(request, None): return HttpResponseRedirect(self.reverse('admin:index')) return HttpResponseRedirect( self.reverse('admin:%s_%s_changelist' % (opts.app_label, opts.model_name))) object_name = _(u'%s Translation') % force_text(opts.verbose_name) if perms_needed or protected: title = _(u"Cannot delete %(name)s") % {"name": object_name} else: title = _(u"Are you sure?") return render( request, self.delete_confirmation_template or ("admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/delete_confirmation.html" % app_label, "admin/delete_confirmation.html"), { "title": title, "object_name": object_name, "object": obj, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, }, )
def unpublish_selected(modeladmin, request, queryset): queryset = queryset.select_for_update() opts = modeladmin.model._meta app_label = opts.app_label all_unpublished = [] for obj in queryset: obj_public = obj.unpublish(dry_run=True) if obj_public: all_unpublished.append(obj_public) perms_needed = [] _check_permissions(modeladmin, all_unpublished, request, perms_needed) using = router.db_for_write(modeladmin.model) # Populate unpublishable_objects, a data structure of all related objects that # will also be deleted. unpublishable_objects, _perms_needed, protected = get_deleted_objects( all_unpublished, opts, request.user, modeladmin.admin_site, using) if request.POST.get('post'): if perms_needed: raise PermissionDenied n = len(all_unpublished) if n: for obj in queryset: obj_public = obj.unpublish() if obj_public: modeladmin.log_publication(request, object, message="Unpublished") modeladmin.message_user( request, _("Successfully unpublished %(count)d %(items)s.") % { "count": n, "items": model_ngettext(modeladmin.opts, n) }) # Return None to display the change list page again. return None if len(all_unpublished) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot unpublish %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = { "title": title, "objects_name": objects_name, "unpublishable_objects": [unpublishable_objects], 'queryset': queryset, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, } # Display the confirmation page return TemplateResponse( request, modeladmin.unpublish_confirmation_template or [ "admin/%s/%s/unpublish_selected_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/unpublish_selected_confirmation.html" % app_label, "admin/unpublish_selected_confirmation.html" ], context, current_app=modeladmin.admin_site.name)
"""
def delete_translation(self, request, object_id, language_code): "The 'delete translation' admin view for this model." opts = self.model._meta app_label = opts.app_label translations_model = opts.translations_model try: obj = translations_model.objects.select_related('maser').get( master__pk=unquote(object_id), language_code=language_code) except translations_model.DoesNotExist: raise Http404 if not self.has_delete_permission(request, obj): raise PermissionDenied if len(self.get_available_languages(obj.master)) <= 1: return self.deletion_not_allowed(request, obj, language_code) using = router.db_for_write(translations_model) # Populate deleted_objects, a data structure of all related objects that # will also be deleted. protected = False deleted_objects, perms_needed, protected = get_deleted_objects( [obj], translations_model._meta, request.user, self.admin_site, using) lang = get_language_name(language_code) if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = '%s translation of %s' % (lang, force_unicode(obj.master)) self.log_deletion(request, obj, obj_display) self.delete_model_translation(request, obj) self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % { 'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display) } ) if not self.has_change_permission(request, None): return HttpResponseRedirect(self.reverse('admin:index')) model_name = opts.model_name if django.VERSION >= (1, 6) else opts.module_name return HttpResponseRedirect(self.reverse('admin:%s_%s_changelist' % (opts.app_label, model_name))) object_name = '%s Translation' % force_unicode(opts.verbose_name) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": object_name} else: title = _("Are you sure?") context = { "title": title, "object_name": object_name, "object": obj, "deleted_objects": deleted_objects, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "app_label": app_label, } # in django > 1.4 root_path is removed if hasattr(self.admin_site, 'root_path'): context.update({"root_path": self.admin_site.root_path}) return render_to_response(self.delete_confirmation_template or [ "admin/%s/%s/delete_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/delete_confirmation.html" % app_label, "admin/delete_confirmation.html" ], context, RequestContext(request))
def delete_selected_vidyo_models(self, request, queryset): """The first half of this method is copied practically verbatim from django.contrib.admin.actions.delete_selected. However, the actual deletion is done within this method because django.contrib.admin uses queryset.delete() for efficiency. That method precludes the use of RPC. """ opts = self.model._meta # Check that the user has delete permission for the actual model if not self.has_delete_permission(request): raise PermissionDenied() using = router.db_for_write(self.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, self.admin_site, using ) # If the POST querydict has get('post'), that means the submit button # has been submitted: Go ahead and delete if request.POST.get('post'): password = request.POST.get('password') if not password: self.message_user(request, _("Password Required"), messages.ERROR) return None if perms_needed: raise PermissionDenied() deleted_models = 0 for obj in queryset: obj_display = force_text(obj) self.log_deletion(request, obj, obj_display) try: obj.decrypt(password) except ValueError: continue obj.delete() deleted_models += 1 if len(queryset) > deleted_models: self.message_user( request, _("couldn't delete all %ss: some were skipped") % str(type(self)), messages.WARNING ) else: self.message_user( request, _("Successfully deleted %(number)s %(type)ss") % { 'number': deleted_models, 'type': self.model }, messages.SUCCESS ) return None # If the POST doesn't contain 'post' key that means we're not yet ready # to do the full deletion, so let django.contrib.admin render the # confirmation page with our overridden template else: return delete_selected(self, request, queryset)
def delete_topic(self, request, queryset): ''' This method remove forum selected in the admin django. Can remove one o more records. ''' if not self.has_delete_permission(request): raise PermissionDenied if request.POST.get("post"): for obj in queryset: idforum = obj.idforum if not obj.moderators.is_superuser: if obj.moderators: # Return forums that moderating one moderator tot_forum_moderator = Forum.objects.filter( moderators=obj.moderators).count() # Only remove permissions if is moderator one forum if tot_forum_moderator <= 1: try: u = User.objects.get(username=obj.moderators) u.user_permissions.clear() except Exception: pass # Delete record Forum.objects.filter(idforum=idforum).delete() n = queryset.count() self.message_user( request, _("Successfully deleted %(count)d record/s.") % { "count": n, }, messages.SUCCESS ) return None else: opts = self.model._meta if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) using = router.db_for_write(self.model) del_obj, model_c, perms_n, protected = get_deleted_objects( queryset, opts, request.user, self.admin_site, using ) context = { 'title': "", 'delete_topic': [queryset], 'ids': queryset.values_list("idforum"), 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'opts': opts, 'objects_name': objects_name, 'deletable_objects': [del_obj], } return TemplateResponse( request, 'musette/admin/confirm_delete.html', context, current_app=self.admin_site.name )
def _delete_selected(modeladmin, request, queryset): """ Default action which deletes the selected objects. This action first displays a confirmation page whichs shows all the deleteable objects, or, if the user has no permission one of the related childs (foreignkeys), a "permission denied" message. Next, it delets all selected objects and redirects back to the change list. """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. # TODO: Permissions would be so cool... deletable_objects, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, modeladmin.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = len(queryset) if n: for obj in queryset: obj_display = force_unicode(obj) modeladmin.log_deletion(request, obj, obj_display) # call the objects delete method to ensure signals are # processed. obj.delete() # This is what you get if you have to monkey patch every object in a changelist # No queryset object, I can tell ya. So we get a new one and delete that. #pk_list = [o.pk for o in queryset] #klass = queryset[0].__class__ #qs = klass.objects.filter(pk__in=pk_list) #qs.delete() modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % { "count": n, "items": model_ngettext(modeladmin.opts, n) }) # Return None to display the change list page again. return None if len(queryset) == 1: objects_name = force_unicode(opts.verbose_name) else: objects_name = force_unicode(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = { "title": title, "objects_name": objects_name, "deletable_objects": [deletable_objects], 'queryset': queryset, "perms_lacking": perms_needed, "protected": protected, "opts": opts, "root_path": modeladmin.admin_site.root_path, "app_label": app_label, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, } # Display the confirmation page return render_to_response(modeladmin.delete_selected_confirmation_template or [ "admin/%s/%s/delete_selected_confirmation.html" % (app_label, opts.object_name.lower()), "admin/%s/delete_selected_confirmation.html" % app_label, "admin/delete_selected_confirmation.html" ], context, context_instance=template.RequestContext(request))
def delete_selected(modeladmin, request, queryset): """ Override default action which deletes the selected objects to handle and display delete exceptions This action first displays a confirmation page whichs shows all the deleteable objects, or, if the user has no permission one of the related childs (foreignkeys), a "permission denied" message. Next, it deletes all selected objects and redirects back to the change list. """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, opts, request.user, modeladmin.admin_site, using) # The user has already confirmed the deletion. # Do the deletion and return a None to display the change list view again. if request.POST.get('post'): if perms_needed: raise PermissionDenied n = queryset.count() if n: # start: base changes try: queryset.delete() except Exception as e: modeladmin.message_user(request, e.message, messages.ERROR) return None # end: base changes for obj in queryset: obj_display = force_text(obj) modeladmin.log_deletion(request, obj, obj_display) 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 if len(queryset) == 1: objects_name = force_text(opts.verbose_name) else: objects_name = force_text(opts.verbose_name_plural) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = dict( modeladmin.admin_site.each_context(request), title=title, objects_name=objects_name, deletable_objects=[deletable_objects], model_count=dict(model_count).items(), queryset=queryset, perms_lacking=perms_needed, protected=protected, opts=opts, action_checkbox_name=helpers.ACTION_CHECKBOX_NAME, ) 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)
def delete_translation(self, request, object_id, extra_context=None): if 'language' in request.GET: language = request.GET['language'] else: language = get_language_from_request(request) opts = Article._meta titleopts = Title._meta app_label = titleopts.app_label pluginopts = CMSPlugin._meta try: obj = self.get_queryset(request).get(pk=unquote(object_id)) except self.model.DoesNotExist: # Don't raise Http404 just yet, because we haven't checked # permissions yet. We don't want an unauthenticated user to be able # to determine whether a given object exists. obj = None if not self.has_delete_permission(request, obj): return HttpResponseForbidden(force_text(_('You do not have permission to change this article'))) if obj is None: raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id) }) if not len(list(obj.get_languages())) > 1: raise Http404(_('There only exists one translation for this article')) titleobj = get_object_or_404(Title, article__id=object_id, language=language) saved_plugins = CMSPlugin.objects.filter(placeholder__article__id=object_id, language=language) using = router.db_for_read(self.model) kwargs = { 'admin_site': self.admin_site, 'user': request.user, 'using': using } deleted_objects, __, perms_needed = get_deleted_objects( [titleobj], titleopts, **kwargs )[:3] to_delete_plugins, __, perms_needed_plugins = get_deleted_objects( saved_plugins, pluginopts, **kwargs )[:3] deleted_objects.append(to_delete_plugins) perms_needed = set(list(perms_needed) + list(perms_needed_plugins)) if request.method == 'POST': if perms_needed: raise PermissionDenied message = _('Title and plugins with language %(language)s was deleted') % { 'language': force_text(get_language_object(language)['name']) } self.log_change(request, titleobj, message) messages.info(request, message) titleobj.delete() for p in saved_plugins: p.delete() public = obj.publisher_public if public: public.save() if not self.has_change_permission(request, None): return HttpResponseRedirect(admin_reverse('index')) return HttpResponseRedirect(admin_reverse('cms_articles_article_changelist')) context = { 'title': _('Are you sure?'), 'object_name': force_text(titleopts.verbose_name), 'object': titleobj, 'deleted_objects': deleted_objects, 'perms_lacking': perms_needed, 'opts': opts, 'root_path': admin_reverse('index'), 'app_label': app_label, } context.update(extra_context or {}) request.current_app = self.admin_site.name return render(request, self.delete_confirmation_template or [ 'admin/%s/%s/delete_confirmation.html' % (app_label, titleopts.object_name.lower()), 'admin/%s/delete_confirmation.html' % app_label, 'admin/delete_confirmation.html' ], context)
def delete_selected(modeladmin, request, queryset): """ Default action which deletes the selected objects. This action first displays a confirmation page which shows all the deletable objects, or, if the user has no permission one of the related childs (foreignkeys), a "permission denied" message. Next, it deletes all selected objects and redirects back to the change list. """ opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has delete permission for the actual model if not modeladmin.has_delete_permission(request): raise PermissionDenied using = router.db_for_write(modeladmin.model) # Populate deletable_objects, a data structure of all related objects that # will also be deleted. deletable_objects, model_count, perms_needed, protected = get_deleted_objects( queryset, request.user, modeladmin.admin_site, using, ) # 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 objects_name = model_ngettext(queryset) if perms_needed or protected: title = _("Cannot delete %(name)s") % {"name": objects_name} else: title = _("Are you sure?") context = { **modeladmin.admin_site.each_context(request), 'title': title, 'objects_name': str(objects_name), 'deletable_objects': [deletable_objects], 'model_count': dict(model_count).items(), 'queryset': queryset, 'perms_lacking': perms_needed, 'protected': protected, 'opts': opts, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'media': modeladmin.media, } 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)
def delete_view(self, request, object_id, extra_context=None): """ The 'delete' admin view for this model. """ opts = self.model._meta app_label = opts.app_label to_field = request.POST.get('_to_field', request.GET.get('_to_field')) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField( "The field %s cannot be referenced." % to_field) obj = self.get_object(request, unquote(object_id)) if not self.has_delete_permission(request, obj): raise PermissionDenied if obj is None: # Translators: Translation included with Django raise Http404( _('%(name)s object with primary key %(key)r does not exist.') % { 'name': force_text(opts.verbose_name), 'key': escape(object_id) }) # frePPLe specific selection of the database using = request.database # Populate deleted_objects, a data structure of all related objects that # will also be deleted. (deleted_objects, model_count, perms_needed, protected) = get_deleted_objects([obj], opts, request.user, self.admin_site, using) # Update the links to the related objects. frePPLe specific. if request.prefix: def replace_url(a): if isinstance(a, list): return [replace_url(i) for i in a] else: return mark_safe( a.replace('href="', 'href="%s' % request.prefix)) deleted_objects = [replace_url(i) for i in deleted_objects] protected = [replace_url(i) for i in protected] if request.POST: # The user has already confirmed the deletion. if perms_needed: raise PermissionDenied obj_display = force_text(obj) attr = str(to_field) if to_field else opts.pk.attname obj_id = obj.serializable_value(attr) self.log_deletion(request, obj, obj_display) self.delete_model(request, obj) return self.response_delete(request, obj_display, obj_id) object_name = force_text(opts.verbose_name) context = dict( self.admin_site.each_context(request), title=capfirst(object_name + ' ' + unquote(object_id)), object_name=object_name, object=obj, deleted_objects=deleted_objects, model_count=dict(model_count).items(), perms_lacking=perms_needed, protected=protected, opts=opts, app_label=app_label, preserved_filters=self.get_preserved_filters(request), is_popup=('_popup' in request.POST or '_popup' in request.GET), to_field=to_field, ) context.update(extra_context or {}) return self.render_delete_form(request, context)