Ejemplo n.º 1
0
    def really_delete_selected(self, request, queryset):
        deleted_count = 0
        protected_count = 0

        # Check that the user has delete permission for the actual model
        if not self.has_delete_permission(request):
            raise PermissionDenied

        for obj in queryset:
            try:
                obj.delete()
                deleted_count += 1
            except ProtectedError:
                protected_count += 1

        if deleted_count:
            messages.add_message(request, messages.INFO, _("Successfully deleted %(count)d %(items)s.") % {
                "count": deleted_count, "items": model_ngettext(self.opts, deleted_count)
            })

        if protected_count:
            # TODO More informative feedback, possibly with an intermediate screen. Compare messages on trying to delete one object.
            messages.add_message(request, messages.ERROR, _(
                "%(count)d %(items)s not deleted, because that would require deleting protected related objects.") % {
                                     "count": protected_count, "items": model_ngettext(self.opts, protected_count)
                                 })
Ejemplo n.º 2
0
    def undelete_selected(self, request, queryset):
        """ Admin action to undelete objects in bulk with confirmation. """
        if not self.has_delete_permission(request):
            raise PermissionDenied
        assert hasattr(queryset, 'undelete')

        # Remove not deleted item from queryset
        queryset = queryset.filter(deleted=True)
        # Undeletion confirmed
        if request.POST.get('post'):
            n = queryset.count()
            if n:
                for obj in queryset:
                    obj_display = force_text(obj)
                    self.log_undeletion(request, obj, obj_display)
                queryset.undelete()
                if django.VERSION[1] <= 4:
                    self.message_user(
                        request,
                        _("Successfully undeleted %(count)d %(items)s.") % {
                            "count": n, "items": model_ngettext(self.opts, n)
                        },
                    )
                else:
                    self.message_user(
                        request,
                        _("Successfully undeleted %(count)d %(items)s.") % {
                            "count": n, "items": model_ngettext(self.opts, n)
                        },
                        messages.SUCCESS,
                    )
                # Return None to display the change list page again.
                return None

        opts = self.model._meta
        if len(queryset) == 1:
            objects_name = force_text(opts.verbose_name)
        else:
            objects_name = force_text(opts.verbose_name_plural)
        title = _("Are you sure?")

        context = {
            'title': title,
            'objects_name': objects_name,
            'queryset': queryset,
            "opts": opts,
            "app_label": opts.app_label,
            'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        }

        return TemplateResponse(
            request,
            self.undelete_selected_confirmation_template,
            context,
            current_app=self.admin_site.name,
        )
Ejemplo n.º 3
0
 def clear_api_cache(self, request, queryset):
     for instance in queryset:
         instance.api(clear=True)
     count = len(queryset)
     message = 'Cleared API cache for {count} {items}.'.format(
         count=count, items=model_ngettext(self.opts, count))
     self.message_user(request, message)
Ejemplo n.º 4
0
    def promote_to_ra(self, request, queryset):
        from django.contrib import messages
        from django.contrib.admin import helpers
        from django.contrib.admin.utils import model_ngettext
        if request.POST.get('post'):
            n = queryset.count()
            if n:
                for org in queryset.all():
                    org.promote_to_registration_authority()
                self.message_user(request, _("Successfully promoted %(count)d %(items)s.") % {
                    "count": n, "items": model_ngettext(self.opts, n)
                }, messages.SUCCESS)
            # Return None to display the change list page again.
            return None

        context = dict(
            self.admin_site.each_context(request),
            title=_("Are you sure?"),
            queryset=queryset,
            action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
            media=self.media,
            opts=self.model._meta
        )

        request.current_app = self.admin_site.name

        # Display the confirmation page
        from django.template.response import TemplateResponse
        return TemplateResponse(request, ["admin/promote_org_to_ra.html"], context)
Ejemplo n.º 5
0
    def make_dirty(self, request, queryset):
        rows_updated = queryset.filter(publisher_state=self.model.PUBLISHER_STATE_PUBLISHED) \
            .update(publisher_state=self.model.PUBLISHER_STATE_CHANGED)

        message = _('{count} {verbose_name} marked as changed.').format(
            count=rows_updated, verbose_name=model_ngettext(self.opts, rows_updated)
        )
        self.message_user(request, message, messages.SUCCESS)
Ejemplo n.º 6
0
    def delete_selected(self, request, queryset):
        if not self.has_delete_permission(request):
            raise PermissionDenied

        hearing_count = queryset.count()
        if hearing_count:
            for hearing in queryset:
                hearing.soft_delete()
            self.message_user(request, _('Successfully deleted %(count)d %(items)s.') % {
                'count': hearing_count, 'items': model_ngettext(self.opts, hearing_count)
            })
Ejemplo n.º 7
0
 def _set_objects_active(self, request, queryset, active):
     """ Sets the 'is_active' property of each item in ``queryset`` to ``active`` and reports success to the user. """
     # We call save on each object instead of using queryset.update to allow for custom save methods and hooks.
     count = 0
     for obj in queryset.select_for_update():
         obj.is_active = active
         obj.save(update_fields=['is_active'])
         count += 1
     self.message_user(request, _("Successfully %(prefix)sactivated %(count)d %(items)s.") % {
         "prefix": "" if active else "de", "count": count, "items": model_ngettext(self.opts, count)
     })
Ejemplo n.º 8
0
def reset_to_pending(modeladmin, request, queryset):
    """ Default action to reset selected object's status to pending """
    ip_count = moderate_selected(modeladmin, request, queryset, PENDING_STATUS)
    if ip_count:
        modeladmin.message_user(
            request,
            _("Successfully reset status of %(count)d %(items)s.") % {
                'count': ip_count,
                'items': model_ngettext(modeladmin.opts, ip_count)
            }
        )
    return None
Ejemplo n.º 9
0
Archivo: admin.py Proyecto: Osmose/kuma
def censor_selected(modeladmin, request, queryset):
    """
    Censor the selected submissions, with confirmation interstitial.

    Largely stolen from django.contrib.admin.actions.delete_selected
    """
    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

    # 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'):
        censored_url = request.POST.get('censored_url', None)
        n = queryset.count()
        if n:
            for obj in queryset:
                obj.censor(url=censored_url)
                obj_display = force_unicode(obj)
                modeladmin.message_user(request, _("Censored %(item)s") % {
                    "item": obj_display
                })
            modeladmin.message_user(
                request,
                _("Successfully censored %(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)

    context = {
        "title": _("Are you sure?"),
        "object_name": objects_name,
        "queryset": queryset,
        "opts": opts,
        "app_label": app_label,
        "action_checkbox_name": helpers.ACTION_CHECKBOX_NAME,
    }

    # Display the confirmation page
    return TemplateResponse(
        request,
        'admin/demos/submission/censor_selected_confirmation.html',
        context, current_app=modeladmin.admin_site.name)
Ejemplo n.º 10
0
def challenge_selected(modeladmin, request, queryset):
    """ Default action to challenge selected objects """
    ch_count = moderate_selected(modeladmin, request, queryset, CHALLENGED_STATUS)
    if ch_count:
        modeladmin.message_user(
            request,
            _("Successfully challenged %(count)d %(items)s.") % {
                "count": ch_count,
                "items": model_ngettext(modeladmin.opts, ch_count)
            }
        )
    # Return None to display the change list page again.
    return None
Ejemplo n.º 11
0
def approve_selected(modeladmin, request, queryset):
    """ Default action to approve selected objects """
    ap_count = moderate_selected(modeladmin, request, queryset, APPROVED_STATUS)
    if ap_count:
        modeladmin.message_user(
            request,
            _("Successfully approved %(count)d %(items)s.") % {
                "count": ap_count,
                "items": model_ngettext(modeladmin.opts, ap_count)
            }
        )
    # Return None to display the change list page again.
    return None
Ejemplo n.º 12
0
    def send_activation_email(self, request, queryset):
        """
        Send activation emails for the selected users, if they are not already
        activated.
        """
        n = 0
        for user in queryset:
            if not user.is_active and settings.USERS_VERIFY_EMAIL:
                send_activation_email(user=user, request=request)
                n += 1

        self.message_user(
            request, _('Activation emails sent to %(count)d %(items)s.') %
            {'count': n, 'items': model_ngettext(self.opts, n)},  messages.SUCCESS)
Ejemplo n.º 13
0
 def delete_models(self, queryset):
     n = queryset.count()
     if n:
         if self.delete_models_batch:
             if(self.model_name=='view'):
                 for data in queryset:
                     for field in data._meta.fields:
                         if(field.name=='subjecttype'):
                             s = getattr(data, 'subjecttype')
                             if (s != '-1'):
                                 id = getattr(data, 'id')
                                 FileExtendInfo.objects.filter(fileId=str(id)).delete()
                         s = getattr(data,field.name)
                         if(os.path.isfile('./media/'+str(s))==True):
                             if(str(s).find("/quanjing/")==-1):
                                 os.remove('./media/' + str(s))
                             else:
                                 s = str(s).split("/")
                                 str1 = s[0:3]
                                 str1 = '/'.join(str1)
                                 if(os.path.isdir('./media/'+str1)):
                                     shutil.rmtree('./media/'+str1)
                                 if(os.path.exists('./media/'+str1+'.zip')):
                                     os.remove('./media/'+str1+'.zip')
             queryset.delete()
         else:
             for obj in queryset:
                 if (self.model_name == 'view'):
                     for field in obj._meta.fields:
                         if (field.name == 'subjecttype'):
                             s = getattr(obj, 'subjecttype')
                             if (s != '-1'):
                                 id = getattr(obj, 'id')
                                 FileExtendInfo.objects.filter(fileId=str(id)).delete()
                         s = getattr(obj, field.name)
                         if (os.path.isfile('./media/' + str(s)) == True):
                             if (str(s).find("/quanjing/") == -1):
                                 os.remove('./media/' + str(s))
                             else:
                                 s = str(s).split("/")
                                 str1 = s[0:3]
                                 str1 = '/'.join(str1)
                                 if (os.path.isdir('./media/' + str1)):
                                     shutil.rmtree('./media/' + str1)
                                 if (os.path.exists('./media/' + str1 + '.zip')):
                                     os.remove('./media/' + str1 + '.zip')
                 obj.delete()
         self.message_user(_("Successfully deleted %(count)d %(items)s.") % {
             "count": n, "items": model_ngettext(self.opts, n)
         }, 'success')
Ejemplo n.º 14
0
    def activate_users(self, request, queryset):
        """
        Activates the selected users, if they are not already
        activated.

        """
        n = 0
        for user in queryset:
            if not user.is_active:
                user.activate()
                n += 1
        self.message_user(
            request,
            _('Successfully activated %(count)d %(items)s.') %
            {'count': n, 'items': model_ngettext(self.opts, n)},  messages.SUCCESS)
Ejemplo n.º 15
0
def delete_selected(modeladmin, request, queryset):
    """
    Переопределено множественное удаление записи.
    Добавляем в исключение lock_id_list
    
    """
    
    lock_id_list = getattr(modeladmin, 'lock_id_list', [])
  
    queryset_without_lock = queryset.exclude(id__in=lock_id_list)
    count_lock = queryset.filter(id__in=lock_id_list).count()
    if count_lock: 
        modeladmin.message_user(request, _('%(count)d %(items)s not may be deleted.') % {
            'count': count_lock, 'items': model_ngettext(modeladmin.opts, count_lock)
        }, messages.WARNING)
    return delete_selected_(modeladmin, request, queryset_without_lock)
Ejemplo n.º 16
0
    def activate_users(self, request, queryset):
        """
        Activates the selected users, if they are not already
        activated.

        """
        n = 0
        for user in queryset:
            if not user.is_active:
                user.activate()
                n += 1
        self.message_user(
            request,
            _('Successfully activated %(count)d %(items)s.') % {
                'count': n,
                'items': model_ngettext(self.opts, n)
            }, messages.SUCCESS)
Ejemplo n.º 17
0
    def send_activation_email(self, request, queryset):
        """
        Send activation emails for the selected users, if they are not already
        activated.
        """
        n = 0
        for user in queryset:
            if not user.is_active and settings.USERS_VERIFY_EMAIL:
                send_activation_email(user=user, request=request)
                n += 1

        self.message_user(
            request,
            _('Activation emails sent to %(count)d %(items)s.') % {
                'count': n,
                'items': model_ngettext(self.opts, n)
            }, messages.SUCCESS)
Ejemplo n.º 18
0
def recreate_vm(modeladmin, request, queryset):
    opts = modeladmin.model._meta

    # 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'):
        n = queryset.count()
        if n:
            for vm in queryset:
                from apimws.vm import destroy_vm, recreate_vm
                try:
                    destroy_vm(vm.id)
                except:
                    pass
                recreate_vm(vm.id)

            modeladmin.message_user(
                request, "Successfully recreated %(count)d %(items)s." % {
                    "count": n,
                    "items": model_ngettext(modeladmin.opts, n)
                }, messages.INFO)
        # 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)

    context = dict(
        modeladmin.admin_site.each_context(request),
        title="Are you sure?",
        objects_name=objects_name,
        list_objects=[queryset],
        queryset=queryset,
        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, "admin/recreate_confirmation.html",
                            context)
Ejemplo n.º 19
0
    def test_process_wire(self, process_payment, message_user) -> None:
        """
        Tests that a wire payment is processed correctly
        """
        object_id = "c85ea333-3508-46f1-8cbb-254f8c138020"
        payment = Payment.objects.create(pk=object_id, amount=7.5)
        queryset = Payment.objects.filter(pk=object_id)
        process_payment.return_value = [payment]
        change_url = reverse("admin:payments_payment_changelist")

        request_noperms = self.client.post(
            change_url,
            {
                "action": "process_wire_selected",
                "index": 1,
                "_selected_action": [object_id],
            },
        ).wsgi_request
        self._give_user_permissions()
        request_hasperms = self.client.post(
            change_url,
            {
                "action": "process_wire_selected",
                "index": 1,
                "_selected_action": [object_id],
            },
        ).wsgi_request

        process_payment.reset_mock()
        message_user.reset_mock()

        self.admin.process_wire_selected(request_noperms, queryset)
        process_payment.assert_not_called()

        self.admin.process_wire_selected(request_hasperms, queryset)
        process_payment.assert_called_once_with(queryset, self.user,
                                                Payment.WIRE)
        message_user.assert_called_once_with(
            request_hasperms,
            _("Successfully processed %(count)d %(items)s.") % {
                "count": 1,
                "items": model_ngettext(Payment(), 1)
            },
            messages.SUCCESS,
        )
Ejemplo n.º 20
0
def get_csv(modeladmin, request, queryset):
    """
    TODO check OOM on big data
    """
    opts = modeladmin.opts

    if request.POST.get('post'):
        field_names = tuple(
            [field.name for field in opts.fields if field.name not in 'password' or not request.user.is_superuser])

        # TODO time format dependency on language
        time_now = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S')
        filename = f'{opts}_{time_now}.csv'

        # Generate streaming response
        pseudo_buffer = Echo()
        streaming_writer = csv.writer(pseudo_buffer, delimiter=',')
        pseudo_buffer.write(field_names)
        response = StreamingHttpResponse(
            (streaming_writer.writerow(row) for row in chain([field_names], [
                [getattr(obj, field) for field in field_names] for obj in queryset
            ])),
            content_type="text/csv")
        response['Content-Disposition'] = f'attachment; filename={filename}'

        return response

    objects_name = model_ngettext(queryset)
    title = _(f'Get CSV from {objects_name} objects')

    context = {
        **modeladmin.admin_site.each_context(request),
        'title': title,
        'queryset': queryset,
        'perms_lacking': [],
        'opts': opts,
        'objects_name': objects_name,
        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        'media': modeladmin.media,
    }

    request.current_app = modeladmin.admin_site.name
    return TemplateResponse(
        request, "admin/admin_actions/get_csv_confirmation.html", context)
Ejemplo n.º 21
0
def soft_delete_selected(modeladmin, request, queryset):
    """
    In charge of deactivating instances instead of deleting them
    """
    opts = modeladmin.model._meta
    using = router.db_for_write(modeladmin.model)
    count = queryset.count()

    if not count:
        return None

    # soft delete selected items
    if hasattr(queryset, 'soft_delete'):
        queryset.soft_delete()
    else:
        for obj in queryset:
            soft_delete_item = getattr(obj, 'soft_delete', None)
            if not soft_delete_item:
                modeladmin.message_user(
                    request,
                    _("{verbose_name_plural} has not soft delete available.".
                      format({"verbose_name_plural":
                              opts.verbose_name_plural})), messages.SUCCESS)
                return None
            soft_delete_item()

    # soft delete nested items
    collector = NestedObjects(using=using)
    collector.collect(queryset)
    for model_base, nested_objects_collected in collector.data.items():
        if model_base == modeladmin.model or not hasattr(
                model_base, 'soft_delete'):
            continue

        for nested_object in nested_objects_collected:
            nested_object.soft_delete()

    # response success message
    modeladmin.message_user(
        request,
        _("Successfully soft deleted {count} {items}.".format(
            count=count, items=model_ngettext(modeladmin.opts, count))),
        messages.SUCCESS)
    return None
Ejemplo n.º 22
0
def delete_selected(modeladmin, request, queryset):
    if not modeladmin.has_delete_permission(request):
        raise PermissionDenied
    if request.POST.get('post'):
        count = queryset.count()
        if count:
            for object in queryset:
                modeladmin.log_deletion(request, object, force_text(object))
            queryset.delete()
            modeladmin.message_user(
                request,
                _(u'Successfully deleted {count:d} {items:s}.').format(
                    count=count,
                    items=model_ngettext(modeladmin.opts, count),
                ),
                messages.SUCCESS,
            )
        return None
    context = dict(
        modeladmin.admin_site.each_context(request),
        action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
        objects_name=force_text(modeladmin.model._meta.verbose_name)
        if len(queryset) == 1 else force_text(
            modeladmin.model._meta.verbose_name_plural),
        opts=modeladmin.model._meta,
        queryset=queryset,
        title=_('Are you sure?'),
    )
    request.current_app = modeladmin.admin_site.name
    return TemplateResponse(
        request,
        modeladmin.delete_selected_confirmation_template or [
            u'admin/{app_label:s}/{model_name:s}/delete_selected_confirmation.html'
            .format(
                app_label=modeladmin.model._meta.app_label,
                model_name=modeladmin.model._meta.model_name,
            ),
            u'admin/{app_label:s}/delete_selected_confirmation.html'.format(
                app_label=modeladmin.model._meta.app_label, ),
            u'admin/delete_selected_confirmation.html',
        ],
        context,
    )
Ejemplo n.º 23
0
 def delete_selected_groups(self, request, queryset):
     if self.get_default_queryset(request, queryset).exists():
         msg = _('Cannot proceed with the delete operation because '
                 'the batch of items contains the default group, '
                 'which cannot be deleted')
         self.message_user(request, msg, messages.ERROR)
         return False
     if not self.has_delete_permission(request):
         raise PermissionDenied
     n = queryset.count()
     if n:
         queryset.delete()
         self.message_user(
             request,
             _("Successfully deleted %(count)d %(items)s.") % {
                 "count": n,
                 "items": model_ngettext(self.opts, n)
             }, messages.SUCCESS)
     return None
Ejemplo n.º 24
0
def hard_delete_selected(modeladmin, request, queryset):
    opts = modeladmin.model._meta  # # pylint: disable=W0212

    deletable_objects, model_count, perms_needed, protected = modeladmin.get_deleted_objects(queryset, request)

    if request.POST.get('post') and not protected:
        if perms_needed:
            raise PermissionDenied
        if queryset.count():
            number_of_rows_deleted, __ = queryset.hard_delete()  # __ = deleted_items
            if number_of_rows_deleted == 1:
                message_bit = _('1 record was')
            else:
                message_bit = _('%(number_of_rows)s records were') % dict(number_of_rows=number_of_rows_deleted)
            message = _('%(message_bit)s deleted') % dict(message_bit=message_bit)
            modeladmin.message_user(request, message)
        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

    return TemplateResponse(request, 'admin/hard_delete_selected_confirmation.html', context)
Ejemplo n.º 25
0
    def test_set_last_used(self, update_last_used, message_user) -> None:
        """
        Tests that the last used value is updated
        """
        update_last_used.return_value = 1

        request_noperms = self.rf.post("/", {
            "action": "set_last_used",
            "index": 1,
            "_selected_action": ["bla"]
        })
        request_noperms.user = MagicMock()
        request_noperms.user.has_perm = lambda _: False

        request_hasperms = self.rf.post("/", {
            "action": "set_last_used",
            "index": 1,
            "_selected_action": ["bla"]
        })
        request_hasperms.user = MagicMock()
        request_hasperms.user.has_perm = lambda _: True

        update_last_used.reset_mock()
        message_user.reset_mock()

        queryset_mock = MagicMock()

        self.admin.set_last_used(request_noperms, queryset_mock)
        update_last_used.assert_not_called()

        self.admin.set_last_used(request_hasperms, queryset_mock)
        update_last_used.assert_called_once_with(queryset_mock)

        message_user.assert_called_once_with(
            request_hasperms,
            _("Successfully updated %(count)d %(items)s.") % {
                "count": 1,
                "items": model_ngettext(BankAccount(), 1)
            },
            messages.SUCCESS,
        )
Ejemplo n.º 26
0
 def get_context_data(self, form, **kw):
     """Returns additional context for the admin site template"""
     context = super(TaggitBulkWizard, self).get_context_data(form, **kw)
     options = self.get_options()
     data = {}
     data.update(self.request.session[options['session_prefix']])
     content_type = ContentType.objects.get_by_natural_key(data['app_label'], data['model'])
     model = content_type.model_class()
     context.update({
         'title': _('Bulk tagging %(number)s %(model_name)s') % {
             'model_name': model_ngettext(model._meta, len(data['ids'])),
             'number': len(data['ids'])
         },
         'site_title': admin.site.site_title,
         'site_header': admin.site.site_header,
         'index_title': admin.site.index_title,
         'has_permission': admin.site.has_permission(self.request),
         'available_apps': admin.site.get_app_list(self.request),
         'is_popup': False,
     })
     return context
Ejemplo n.º 27
0
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('.')
Ejemplo n.º 28
0
    def test_reject(self, reject_entries):
        reject_entries.return_value = 1

        queryset = []

        request = _get_mock_request([])

        self.admin.reject_selected(request, queryset)
        reject_entries.assert_not_called()

        request = _get_mock_request(["registrations.review_entries"])
        self.admin.reject_selected(request, queryset)
        reject_entries.assert_called_once_with(1, queryset)

        request._messages.add.assert_called_once_with(
            messages.SUCCESS,
            _("Successfully rejected %(count)d %(items)s.") % {
                "count": 1,
                "items": model_ngettext(Renewal(), 1)
            },
            "",
        )
Ejemplo n.º 29
0
    def merge_topics(modeladmin, request, queryset):

        if request.POST.get("post"):
            selected = Topic.objects.get(pk=request.POST["selected"])

            for obj in queryset:
                if obj.pk == selected.pk:
                    continue
                for article in obj.article_set.all():
                    article.topics.remove(obj)
                    article.topics.add(selected)
                obj.delete()

            if count := queryset.count():
                modeladmin.message_user(
                    request,
                    _("Successfully merged %(count)d %(items)s.") % {
                        "count": count,
                        "items": model_ngettext(modeladmin.opts, count)
                    },
                    messages.SUCCESS,
                )
            return None
Ejemplo n.º 30
0
def change_fields(modeladmin, request, queryset):
    if request.POST.get('post'):
        fields = request.POST.get('fields', {})

        if fields and isinstance(fields, dict):
            msg = _(f'Error: Unknown error')
            try:
                queryset.update(**fields)
                msg = _(f'Fields {", ".join(fields.keys())} updated successfully')
            except (exceptions.FieldDoesNotExist,
                    exceptions.FieldError,
                    exceptions.PermissionDenied,
                    exceptions.TooManyFieldsSent,
                    ValueError, TypeError) as e:
                msg = _(f'Do not try to hack me.')
            finally:
                modeladmin.message_user(request, msg)
        return None

    opts = modeladmin.opts
    objects_name = model_ngettext(queryset)
    title = _(f'Change multiple fields in {objects_name} objects')

    context = {
        **modeladmin.admin_site.each_context(request),
        'title': title,
        'queryset': queryset,
        'perms_lacking': [],
        'opts': opts,
        'objects_name': objects_name,
        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        'media': modeladmin.media,
    }

    request.current_app = modeladmin.admin_site.name
    return TemplateResponse(
        request, "admin/admin_actions/change_fields_confirmation.html", context)
Ejemplo n.º 31
0
    def anonymize(self, request, queryset):
        if not request.POST.get('post'):
            # not confirmed yet; display the confirmation page
            return TemplateResponse(request,"initadmin/anonymize_users_confirmation.html", {
                'opts': self.model._meta,
                'users': queryset,
                'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
            })

        # confirmed; anonymize the users
        count = queryset.count()
        if count:
            for user in queryset:
                Vote.objects.filter(user=user,initiative__state='v').delete()
                Avatar.objects.filter(user=user).delete()
                EmailAddress.objects.filter(user=user).delete()
                avatar_dir = avatar_storage.path(os.path.join("avatars", str(user.pk)))
                if os.path.exists(avatar_dir):
                    rmtree(avatar_dir)
                user.first_name = ''
                user.last_name = ''
                user.email = ''
                user.is_staff = False  # for good measure
                user.is_active = False
                UserConfig.objects.filter(user=user).delete()
                for result in user.signupcoderesult_set.all():
                    result.signup_code.delete() # also deletes the result, by cascading
                while True:
                    user.username = '******' + str(randint(1, 9999999999))
                    if not User.objects.filter(username=user.username).exists():
                        break
                user.save()

            self.message_user(request, "%d %s erfolgreich anonymisiert." % (count, model_ngettext(self.opts, count)), messages.SUCCESS)

        return None
Ejemplo n.º 32
0
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)
Ejemplo n.º 33
0
Archivo: admin.py Proyecto: Osmose/kuma
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)
Ejemplo n.º 34
0
    def groot_view(self, request, object_id):
        # Only allow superusers to edit permissions
        if not request.user.is_superuser:
            raise PermissionDenied

        model = self.model
        opts = model._meta

        obj = self.get_object(request, unquote(object_id))

        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),
            })

        opts = self.model._meta
        app_label = opts.app_label

        group_list = Group.objects.all()
        group_count = group_list.count()

        GroupPermissionForm = get_group_permission_form(
            model_perms=self.get_groot_permissions(request),
        )
        GroupPermissionFormSet = formset_factory(
            GroupPermissionForm, extra=0, min_num=group_count, validate_min=True,
            max_num=group_count)

        obj_group_perms = get_groups_with_perms(obj=obj, attach_perms=True)
        initial_data = []

        for group in group_list:
            try:
                group_perms = obj_group_perms[group]
            except KeyError:
                group_perms = []

            group_initial = {
                'group': group,
            }

            for perm in group_perms:
                field_name = '%s%s' % (PERM_PREFIX, perm)
                group_initial[field_name] = True

            initial_data.append(group_initial)

        formset = GroupPermissionFormSet(request.POST or None, initial=initial_data)

        if formset.is_valid():
            # The user has confirmed the update
            group_count = 0

            for form in formset.forms:
                # Only act on changed data
                if form.has_changed():
                    group_count += 1

                    for field in form.changed_data:
                        group = form.cleaned_data['group']
                        changed_perm = field.replace(PERM_PREFIX, '', 1)
                        add_perm = form.cleaned_data[field]

                        # Change perm action accordingly
                        if add_perm:
                            update_perm = assign_perm
                        else:
                            update_perm = remove_perm

                        update_perm(perm=changed_perm, user_or_group=group, obj=obj)

            if group_count:
                self.message_user(request, _((
                    'Successfully updated permissions for %(count)d %(groups)s.'
                )) % {
                    'count': group_count,
                    'groups': model_ngettext(Group, n=group_count),
                }, messages.SUCCESS)
            else:
                self.message_user(request, _('No permissions were updated.'), messages.INFO)

            return HttpResponseRedirect(request.path)

        context = self.admin_site.each_context(request)

        context.update({
            'title': _('Group permissions: %s') % force_text(obj),
            'object': obj,
            'opts': opts,
            'formset': formset,
            'group_formsets': zip(group_list, formset.forms),
        })

        request.current_app = self.admin_site.name

        template_name = getattr(self, 'group_permissions_template', None) or [
            'admin/%s/%s/group_permissions.html' % (app_label, opts.model_name),
            'admin/%s/group_permissions.html' % app_label,
            'admin/group_permissions.html'
        ]

        # Display the form page
        return TemplateResponse(request, template_name, context)
Ejemplo n.º 35
0
    def undelete_selected(self, request, queryset):
        """ Admin action to undelete objects in bulk with confirmation. """
        if not self.has_delete_permission(request):
            raise PermissionDenied
        assert hasattr(queryset, 'undelete')

        # Remove not deleted item from queryset
        queryset = queryset.filter(deleted__isnull=False)
        # Undeletion confirmed
        if request.POST.get('post'):
            n = queryset.count()
            if n:
                for obj in queryset:
                    obj_display = force_text(obj)
                    self.log_undeletion(request, obj, obj_display)
                queryset.undelete()
                if django.VERSION[1] <= 4:
                    self.message_user(
                        request,
                        _("Successfully undeleted %(count)d %(items)s.") % {
                            "count": n,
                            "items": model_ngettext(self.opts, n)
                        },
                    )
                else:
                    self.message_user(
                        request,
                        _("Successfully undeleted %(count)d %(items)s.") % {
                            "count": n,
                            "items": model_ngettext(self.opts, n)
                        },
                        messages.SUCCESS,
                    )
                # Return None to display the change list page again.
                return None

        opts = self.model._meta
        if len(queryset) == 1:
            objects_name = force_text(opts.verbose_name)
        else:
            objects_name = force_text(opts.verbose_name_plural)
        title = _("Are you sure?")

        context = {
            'title': title,
            'objects_name': objects_name,
            'queryset': queryset,
            "opts": opts,
            "app_label": opts.app_label,
            'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        }

        if LooseVersion(django.get_version()) < LooseVersion('1.10'):
            return TemplateResponse(
                request,
                self.undelete_selected_confirmation_template,
                context,
                current_app=self.admin_site.name,
            )
        else:
            return TemplateResponse(
                request,
                self.undelete_selected_confirmation_template,
                context,
            )
Ejemplo n.º 36
0
    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)
Ejemplo n.º 37
0
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))
Ejemplo n.º 38
0
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)
Ejemplo n.º 39
0
def delete_selected(modeladmin, request, queryset):
    """Default ModelAdmin action that deletes the selected objects.

       Django's default handler doesn't even check the
       has_delete_permission() of corresponding ModelAdmin with specific
       instances (only the general permission), and requires django's User
       model permissions as well. Theese aren't currently used in OIOIOI, so
       this custom method doesn't care about them.

       This implementation checks if deleted model is registered in the
       current AdminSite and if it is, then uses has_delete_permission() with
       it's instance.

       It first displays a confirmation page that shows all the
       deleteable objects, or, if the user has no permission for one of the
       related objects (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

    # Find related objects and check their permissions
    # This is a custom method as well
    to_delete, perms_needed, protected = \
            collect_deleted_objects(modeladmin, request, queryset)

    # 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)
            queryset.delete()
            message_text = _("Successfully deleted %(count)d %(items)s.") % {
                "count": n,
                "items": model_ngettext(modeladmin.opts, n)
            }
            modeladmin.message_user(request, message_text, 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=[to_delete],
        queryset=queryset,
        perms_lacking=perms_needed,
        protected=protected,
        opts=opts,
        action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
    )

    request.current_app = modeladmin.admin_site.name

    custom_template = modeladmin.delete_selected_confirmation_template

    # Display the confirmation page
    return TemplateResponse(request, custom_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)
Ejemplo n.º 40
0
    def groot_view(self, request, object_id):
        # Only allow superusers to edit permissions
        if not request.user.is_superuser:
            raise PermissionDenied

        model = self.model
        opts = model._meta

        obj = self.get_object(request, unquote(object_id))

        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),
                })

        opts = self.model._meta
        app_label = opts.app_label

        group_list = Group.objects.all()
        group_count = group_list.count()

        GroupPermissionForm = get_group_permission_form(
            model_perms=get_perms_for_model(model))
        GroupPermissionFormSet = formset_factory(GroupPermissionForm,
                                                 extra=0,
                                                 min_num=group_count,
                                                 validate_min=True,
                                                 max_num=group_count)

        obj_group_perms = get_groups_with_perms(obj=obj, attach_perms=True)
        initial_data = []

        for group in group_list:
            try:
                group_perms = obj_group_perms[group]
            except KeyError:
                group_perms = []

            group_initial = {
                'group': group,
            }

            for perm in group_perms:
                field_name = '%s%s' % (PERM_PREFIX, perm)
                group_initial[field_name] = True

            initial_data.append(group_initial)

        formset = GroupPermissionFormSet(request.POST or None,
                                         initial=initial_data)

        if formset.is_valid():
            # The user has confirmed the update
            group_count = 0

            for form in formset.forms:
                # Only act on changed data
                if form.has_changed():
                    group_count += 1

                    for field in form.changed_data:
                        group = form.cleaned_data['group']
                        changed_perm = field.replace(PERM_PREFIX, '', 1)
                        add_perm = form.cleaned_data[field]

                        # Change perm action accordingly
                        if add_perm:
                            update_perm = assign_perm
                        else:
                            update_perm = remove_perm

                        update_perm(perm=changed_perm,
                                    user_or_group=group,
                                    obj=obj)

            if group_count:
                self.message_user(
                    request,
                    _(('Successfully updated permissions for %(count)d %(groups)s.'
                       )) % {
                           'count': group_count,
                           'groups': model_ngettext(Group, n=group_count),
                       }, messages.SUCCESS)
            else:
                self.message_user(request, _('No permissions were updated.'),
                                  messages.INFO)

            return HttpResponseRedirect(request.path)

        if django.VERSION >= (1, 8):
            context = self.admin_site.each_context(request)
        else:
            context = self.admin_site.each_context()

        context.update({
            'title': _('Group permissions: %s') % force_text(obj),
            'object': obj,
            'opts': opts,
            'formset': formset,
            'group_formsets': zip(group_list, formset.forms),
        })

        request.current_app = self.admin_site.name

        template_name = getattr(self, 'group_permissions_template', None) or [
            'admin/%s/%s/group_permissions.html' %
            (app_label, opts.model_name),
            'admin/%s/group_permissions.html' % app_label,
            'admin/group_permissions.html'
        ]

        # Display the form page
        return TemplateResponse(request, template_name, context)
Ejemplo n.º 41
0
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)
Ejemplo n.º 42
0
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)
Ejemplo n.º 43
0
def merge_selected_tags(modeladmin, request, queryset):
    """
    Default action which deletes the selected objects.

    This action first displays a confirmation page which 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
    # TOD
    if not modeladmin.has_delete_permission(request):
        raise PermissionDenied

    # 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'):

        winner = modeladmin.model.objects.get(pk=request.POST.get('winner'))

        queryset = queryset.exclude(pk=winner.pk)

        n = queryset.count()
        if n:

            n += 1  # For display we want to include the winner in the count

            for obj in queryset:
                obj_display = force_text(obj)
                modeladmin.log_deletion(request, obj, obj_display)
                winner.merge(obj)

            modeladmin.message_user(request, _("Successfully merged %(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)

    title = _("Are you sure?")

    context = dict(
        modeladmin.admin_site.each_context(request),
        title=title,
        objects_name=objects_name,
        model_count=queryset.count(),
        queryset=queryset,
        opts=opts,
        action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
    )

    request.current_app = modeladmin.admin_site.name

    return render(request, "admin/orb/tag/merge_tags_confirmation.html", context)
Ejemplo n.º 44
0
def delete_related_services(modeladmin, request, queryset):
    opts = modeladmin.model._meta
    app_label = opts.app_label
    
    using = router.db_for_write(modeladmin.model)
    collector = NestedObjects(using=using)
    collector.collect(queryset)
    registered_services = services.get()
    related_services = []
    to_delete = []
    
    user = request.user
    admin_site = modeladmin.admin_site
    
    def format(obj, account=False):
        has_admin = obj.__class__ in admin_site._registry
        opts = obj._meta
        no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), force_text(obj))
        
        if has_admin:
            try:
                admin_url = reverse('admin:%s_%s_change' % (opts.app_label, opts.model_name),
                        None, (quote(obj._get_pk_val()),)
                )
            except NoReverseMatch:
                # Change url doesn't exist -- don't display link to edit
                return no_edit_link
            
            p = '%s.%s' % (opts.app_label, get_permission_codename('delete', opts))
            if not user.has_perm(p):
                perms_needed.add(opts.verbose_name)
            # Display a link to the admin page.
            context = (capfirst(opts.verbose_name), admin_url, obj)
            if account:
                context += (_("services to delete:"),)
                return format_html('{} <a href="{}">{}</a> {}', *context)
            return format_html('{}: <a href="{}">{}</a>', *context)
        else:
            # Don't display link to edit, because it either has no
            # admin or is edited inline.
            return no_edit_link
    
    def format_nested(objs, result):
        if isinstance(objs, list):
            current = []
            for obj in objs:
                format_nested(obj, current)
            result.append(current)
        else:
            result.append(format(objs))
    
    for nested in collector.nested():
        if isinstance(nested, list):
            # Is lists of objects
            current = []
            is_service = False
            for service in nested:
                if type(service) in registered_services:
                    if service == main_systemuser:
                        continue
                    current.append(format(service))
                    to_delete.append(service)
                    is_service = True
                elif is_service and isinstance(service, list):
                    nested = []
                    format_nested(service, nested)
                    current.append(nested)
                    is_service = False
                else:
                    is_service = False
            related_services.append(current)
        elif isinstance(nested, modeladmin.model):
            # Is account
            # Prevent the deletion of the main system user, which will delete the account
            main_systemuser = nested.main_systemuser
            related_services.append(format(nested, account=True))
    
    # 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'):
        n = queryset.count()
        if n:
            for obj in to_delete:
                obj_display = force_text(obj)
                modeladmin.log_deletion(request, obj, obj_display)
                # TODO This probably will fail in certain conditions, just capture exception
                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)
    
    context = dict(
        modeladmin.admin_site.each_context(request),
        title=_("Are you sure?"),
        objects_name=objects_name,
        deletable_objects=[related_services],
        model_count=dict(collector.model_count).items(),
        queryset=queryset,
        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)
Ejemplo n.º 45
0
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)
Ejemplo n.º 46
0
def delete_selected(modeladmin, request, queryset):
    """Default ModelAdmin action that deletes the selected objects.

       Django's default handler doesn't even check the
       has_delete_permission() of corresponding ModelAdmin with specific
       instances (only the general permission), and requires django's User
       model permissions as well. Theese aren't currently used in OIOIOI, so
       this custom method doesn't care about them.

       This implementation checks if deleted model is registered in the
       current AdminSite and if it is, then uses has_delete_permission() with
       it's instance.

       It first displays a confirmation page that shows all the
       deleteable objects, or, if the user has no permission for one of the
       related objects (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

    # Find related objects and check their permissions
    # This is a custom method as well
    to_delete, perms_needed, protected = \
            collect_deleted_objects(modeladmin, request, queryset)

    # 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)
            queryset.delete()
            message_text = _("Successfully deleted %(count)d %(items)s.") % {
                "count": n,
                "items": model_ngettext(modeladmin.opts, n)
            }
            modeladmin.message_user(request, message_text, 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=[to_delete],
        queryset=queryset,
        perms_lacking=perms_needed,
        protected=protected,
        opts=opts,
        action_checkbox_name=helpers.ACTION_CHECKBOX_NAME,
    )

    request.current_app = modeladmin.admin_site.name

    custom_template = modeladmin.delete_selected_confirmation_template

    # Display the confirmation page
    return TemplateResponse(request, custom_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)
Ejemplo n.º 47
0
"""
Ejemplo n.º 48
0
def update_active(modeladmin, request, queryset):
    """
    ENG: Update active for multiple entities
    RUS: Обновление активных элементов для нескольких объектов
    """
    CHUNK_SIZE = getattr(settings, 'EDW_UPDATE_RELATIONS_ACTION_CHUNK_SIZE', 100)

    opts = modeladmin.model._meta
    app_label = opts.app_label

    if request.POST.get('post'):
        form = EntitiesUpdateActiveAdminForm(request.POST)

        if form.is_valid():
            to_set_active = form.cleaned_data['to_set_active']

            n = queryset.count()
            if n:
                i = 0
                tasks = []
                while i < n:
                    chunk = queryset[i:i + CHUNK_SIZE]
                    for obj in chunk:
                        obj_display = force_text(obj)
                        modeladmin.log_change(request, obj, obj_display)

                    tasks.append(update_entities_active.si([x.id for x in chunk], to_set_active))

                    i += CHUNK_SIZE

                chain(reduce(OR, tasks)).apply_async()

                modeladmin.message_user(request, _("Successfully proceed %(count)d %(items)s.") % {
                    "count": n, "items": model_ngettext(modeladmin.opts, n)
                })

            # Return None to display the change list page again.
            return None

    else:
        form = EntitiesUpdateActiveAdminForm()

    if len(queryset) == 1:
        objects_name = force_text(opts.verbose_name)
    else:
        objects_name = force_text(opts.verbose_name_plural)

    title = _("Update active for multiple entities")
    context = {
        "title": title,
        'form': form,
        "objects_name": objects_name,
        'queryset': queryset,
        "opts": opts,
        "app_label": app_label,
        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        'media': modeladmin.media,
        'action': 'update_active',
    }
    # Display the confirmation page
    kwargs = {}
    return TemplateResponse(request, "edw/admin/entities/actions/update_active.html",
                            context, **kwargs)
Ejemplo n.º 49
0
    def remove_selected(self, request, queryset):

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

        # The user has already confirmed the deletion.
        # Do the deletion and return None to display the change list view again.
        if request.POST.get('post') and not protected:
            if perms_needed:
                raise PermissionDenied
            n = queryset.count()
            if n:
                for obj in queryset:
                    obj_display = str(obj)
                    # manually delete the images stored in the cloud
                    if obj.url:
                        try:
                            delete(obj.url)
                        except Exception:
                            continue
                    self.log_deletion(request, obj, obj_display)

                self.delete_queryset(request, queryset)
                self.message_user(
                    request,
                    _("Successfully deleted %(count)d %(items)s.") % {
                        "count": n,
                        "items": model_ngettext(self.opts, n)
                    }, messages.SUCCESS)
            # delete all
            # queryset.delete()
            # Return None to display the change list page again.
            return None
        # intermediate confirmation view
        else:
            objects_name = model_ngettext(queryset)

            if perms_needed or protected:
                title = _("Cannot delete %(name)s") % {"name": objects_name}
            else:
                title = _("Are you sure?")

            context = {
                **self.admin_site.each_context(request),
                'title': title,
                'queryset': queryset,
                'action_checkbox_name': ACTION_CHECKBOX_NAME,
                'opts': self.opts,
                'objects_name': str(objects_name),
                'deletable_objects': [deletable_objects],
                'perms_lacking': perms_needed,
                'protected': protected,
                'model_count': dict(model_count).items(),
                'media': self.media,
            }

            request.current_app = self.admin_site.name

            # Display the confirmation page
            return TemplateResponse(
                request,
                'admin/delete_selected_confirm_images.html',
                context,
            )
Ejemplo n.º 50
0
def update_permissions(modeladmin, request, queryset):
    opts = modeladmin.model._meta
    app_label = opts.app_label

    # Only allow superusers to edit permissions
    if not request.user.is_superuser:
        raise PermissionDenied

    PermissionForm = get_permission_form(modeladmin.model)
    form = PermissionForm()

    # The user has confirmed the update
    if request.POST.get('post'):
        form = PermissionForm(request.POST)

        if form.is_valid():
            groups = form.cleaned_data['groups']
            permissions = form.cleaned_data['permissions']

            # Can be either add or remove varying on button
            if request.POST.get('remove_permissions'):
                update_perm = remove_perm
            else:
                update_perm = assign_perm

            for obj in queryset:
                for group in groups:
                    for permission in permissions:
                        update_perm(perm=permission, user_or_group=group, obj=obj)

            modeladmin.message_user(request, _((
                'Successfully updated permissions for %(group_count)d %(groups)s on '
                '%(obj_count)d %(items)s.')
            ) % {
                'group_count': len(groups),
                'obj_count': queryset.count(),
                'groups': model_ngettext(Group, n=len(groups)),
                'items': model_ngettext(queryset),
            }, messages.SUCCESS)

            # Display change list page again
            return None

    adminForm = helpers.AdminForm(
        form=form,
        fieldsets=[(None, {'fields': form.base_fields})],
        prepopulated_fields={},
        model_admin=modeladmin)

    if len(queryset) == 1:
        objects_name = force_text(opts.verbose_name)
    else:
        objects_name = force_text(opts.verbose_name_plural)

    context = modeladmin.admin_site.each_context(request)

    context.update({
        'title': _('Update permissions'),
        'adminform': adminForm,
        'objects_name': objects_name,
        'queryset': queryset,
        'opts': opts,
        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        'media': modeladmin.media,
        'form': form,
    })

    request.current_app = modeladmin.admin_site.name

    template_name = getattr(modeladmin, 'update_permissions_template', None) or [
        'admin/%s/%s/update_permissions.html' % (app_label, opts.model_name),
        'admin/%s/update_permissions.html' % app_label,
        'admin/update_permissions.html'
    ]

    # Display the form page
    return TemplateResponse(request, template_name, context)
Ejemplo n.º 51
0
def update_states(modeladmin, request, queryset):
    """
    ENG: Update states for multiple entities
    RUS: Обновляет состояния для нескольких объектов
    """
    CHUNK_SIZE = getattr(settings, 'EDW_UPDATE_STATES_ACTION_CHUNK_SIZE', 100)

    opts = modeladmin.model._meta
    app_label = opts.app_label

    try:
        terms_ids = queryset[0].terms.values_list('id', flat=True)
    except IndexError:
        entities_model = DataMartModel.get_base_entity_model()
    else:
        entities_model = DataMartModel.get_entities_model(terms_ids)

    if request.POST.get('post'):
        form = EntitiesUpdateStateAdminForm(request.POST, entities_model=entities_model)

        if form.is_valid():
            state = form.cleaned_data['state']

            n = queryset.count()
            if n and state:
                i = 0
                tasks = []
                while i < n:
                    chunk = queryset[i:i + CHUNK_SIZE]
                    for obj in chunk:
                        obj_display = force_text(obj)
                        modeladmin.log_change(request, obj, obj_display)

                    tasks.append(update_entities_states.si([x.id for x in chunk], state))

                    i += CHUNK_SIZE

                chain(reduce(OR, tasks)).apply_async()

                modeladmin.message_user(request, _("Successfully proceed %(count)d %(items)s.") % {
                    "count": n, "items": model_ngettext(modeladmin.opts, n)
                })

            # Return None to display the change list page again.
            return None
    else:
        form = EntitiesUpdateStateAdminForm(entities_model=entities_model)

    if len(queryset) == 1:
        objects_name = force_text(opts.verbose_name)
    else:
        objects_name = force_text(opts.verbose_name_plural)

    title = _("Update state for multiple entities")
    context = {
        "title": title,
        'form': form,
        "objects_name": objects_name,
        'queryset': queryset,
        "opts": opts,
        "app_label": app_label,
        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        'media': modeladmin.media,
        'action': 'update_states',
    }
    # Display the confirmation page
    kwargs = {}
    return TemplateResponse(request, "edw/admin/entities/actions/update_states.html",
                            context, **kwargs)
Ejemplo n.º 52
0
def copy_selected(modeladmin, request, queryset):
    """
    Action which copies the selected objects.

    This action first displays a confirmation page which shows all the
    creatable objects, or, if the user has no permission one of the related
    childs (foreignkeys), a "permission denied" message.

    Next, it copies all selected objects and redirects back to the change list.
    """
    opts = modeladmin.model._meta
    app_label = opts.app_label

    # Populate creatable_objects, a data structure of all related objects that
    # will also be created.
    creatable_objects, model_count, perms_needed, collector = get_copied_objects(
        queryset, request, modeladmin.admin_site,
        handlers=getattr(modeladmin, 'copy_selected_handlers', None)
    )

    # The user has already confirmed the deletion.
    # Do the creation and return 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:
                change_message = modeladmin.construct_change_message(
                    request, None, None, True)
                modeladmin.log_addition(request, obj, change_message)
            # copy all objects with related objects
            collector.copy()
            modeladmin.message_user(
                request, _("Successfully created %(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:
        title = _("Cannot create %(name)s") % {"name": objects_name,}
    else:
        title = _("Are you sure?")

    context = {
        **modeladmin.admin_site.each_context(request),
        'title': title,
        'objects_name': str(objects_name),
        'creatable_objects': [creatable_objects],
        'model_count': dict(model_count).items(),
        'queryset': queryset,
        'perms_lacking': perms_needed,
        '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,
        getattr(modeladmin, 'copy_selected_confirmation_template', None) or [
            "admin/%s/%s/copy_selected_confirmation.html" % (app_label, opts.model_name),
            "admin/%s/copy_selected_confirmation.html" % app_label,
            "admin/copy_selected_confirmation.html"
        ],
        context
    )
Ejemplo n.º 53
0
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 update_additional_characteristics_or_marks(modeladmin, request, queryset):
    """
    ENG: Update additional marks for multiple entities
    RUS: Обновление дополнительных характеристик или меток для нескольких объектов
    """
    CHUNK_SIZE = getattr(
        settings,
        'EDW_UPDATE_ADDITIONAL_CHARACTERISTICS_OR_MARKS_ACTION_CHUNK_SIZE',
        100)

    opts = modeladmin.model._meta
    app_label = opts.app_label

    if request.POST.get('post'):
        form = EntitiesUpdateAdditionalCharacteristicsOrMarksAdminForm(
            request.POST)
        if form.is_valid():
            to_set_term = form.cleaned_data['to_set_term']
            to_unset_term = form.cleaned_data['to_unset_term']
            value = form.cleaned_data['value']
            view_class = form.cleaned_data['view_class']

            n = queryset.count()
            if n and (to_set_term and value or to_unset_term):
                i = 0
                tasks = []
                while i < n:
                    chunk = queryset[i:i + CHUNK_SIZE]
                    for obj in chunk:
                        obj_display = force_text(obj)
                        modeladmin.log_change(request, obj, obj_display)

                    tasks.append(
                        update_entities_additional_characteristics_or_marks.si(
                            [x.id for x in chunk],
                            to_set_term.id if to_set_term else None, value,
                            view_class,
                            to_unset_term.id if to_unset_term else None))
                    i += CHUNK_SIZE

                chain(reduce(OR, tasks)).apply_async()

                modeladmin.message_user(
                    request,
                    _("Successfully proceed %(count)d %(items)s.") % {
                        "count": n,
                        "items": model_ngettext(modeladmin.opts, n)
                    })
            # Return None to display the change list page again.
            return None
    else:
        form = EntitiesUpdateAdditionalCharacteristicsOrMarksAdminForm()

    if len(queryset) == 1:
        objects_name = force_text(opts.verbose_name)
    else:
        objects_name = force_text(opts.verbose_name_plural)

    title = _(
        "Update additional characteristics or marks for multiple entities")
    context = {
        "title": title,
        'form': form,
        "objects_name": objects_name,
        'queryset': queryset,
        "opts": opts,
        "app_label": app_label,
        'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
        'media': modeladmin.media,
        'action': 'update_additional_characteristics_or_marks',
    }
    # Display the confirmation page
    kwargs = {}
    return TemplateResponse(
        request,
        "edw/admin/entities/actions/update_additional_characteristics_or_marks.html",
        context, **kwargs)
Ejemplo n.º 55
0
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)
Ejemplo n.º 56
0
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)
Ejemplo n.º 57
0
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.txt 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

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

    # The user.txt 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)
Ejemplo n.º 58
0
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)
Ejemplo n.º 59
0
    def undelete_selected(self, request, queryset):
        """ Admin action to undelete objects in bulk with confirmation. """
        original_queryset = queryset.all()
        if not self.has_delete_permission(request):
            raise PermissionDenied
        assert hasattr(queryset, 'undelete')

        # Remove not deleted item from queryset
        queryset = queryset.filter(**{FIELD_NAME + '__isnull': False})
        # Undeletion confirmed
        if request.POST.get('post'):
            requested = queryset.count()
            if requested:
                for obj in queryset:
                    obj_display = force_str(obj)
                    self.log_undeletion(request, obj, obj_display)
                queryset.undelete()
                changed = original_queryset.filter(**{FIELD_NAME + '__isnull': True}).count()
                if changed < requested:
                    self.message_user(
                        request,
                        _("Successfully undeleted %(count_changed)d of the "
                          "%(count_requested)d selected %(items)s.") % {
                            "count_requested": requested,
                            "count_changed": changed,
                            "items": model_ngettext(self.opts, requested)
                        },
                        messages.WARNING,
                    )
                else:
                    self.message_user(
                        request,
                        _("Successfully undeleted %(count)d %(items)s.") % {
                            "count": requested,
                            "items": model_ngettext(self.opts, requested)
                        },
                        messages.SUCCESS,
                    )
                # Return None to display the change list page again.
                return None

        opts = self.model._meta
        if len(queryset) == 1:
            objects_name = force_str(opts.verbose_name)
        else:
            objects_name = force_str(opts.verbose_name_plural)
        title = _("Are you sure?")

        related_list = [list(related_objects(obj)) for obj in queryset]

        context = {
            'title': title,
            'objects_name': objects_name,
            'queryset': queryset,
            "opts": opts,
            "app_label": opts.app_label,
            'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
            'related_list': related_list
        }

        if parse_version(django.get_version()) < parse_version('1.10'):
            return TemplateResponse(
                request,
                self.undelete_selected_confirmation_template,
                context,
                current_app=self.admin_site.name,
            )
        else:
            return TemplateResponse(
                request,
                self.undelete_selected_confirmation_template,
                context,
            )
Ejemplo n.º 60
0
 def deactivate_objects(self, request, queryset):
     """Admin action to set is_active=False on objects"""
     count = queryset.update(is_active=False)
     self.message_user(request, _("Successfully deactivated %(count)d %(items)s.") % {
         "count": count, "items": model_ngettext(self.opts, count)
     })