Esempio n. 1
0
    def __init__(self, request, model, list_display, list_display_links,
                 list_filter, date_hierarchy, search_fields,
                 list_select_related, list_per_page, list_max_show_all,
                 list_editable, model_admin):
        self.model = model
        self.opts = model._meta
        self.lookup_opts = self.opts
        self.root_queryset = model_admin.get_queryset(request)
        self.list_display = list_display
        self.list_display_links = list_display_links
        self.list_filter = list_filter
        self.date_hierarchy = date_hierarchy
        self.search_fields = search_fields
        self.list_select_related = list_select_related
        self.list_per_page = list_per_page
        self.list_max_show_all = list_max_show_all
        self.model_admin = model_admin
        self.preserved_filters = model_admin.get_preserved_filters(request)

        # Get search parameters from the query string.
        try:
            self.page_num = int(request.GET.get(PAGE_VAR, 0))
        except ValueError:
            self.page_num = 0
        self.show_all = ALL_VAR in request.GET
        self.is_popup = IS_POPUP_VAR in request.GET
        to_field = request.GET.get(TO_FIELD_VAR)
        if to_field and not model_admin.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)
        self.to_field = to_field
        self.params = dict(request.GET.items())
        if PAGE_VAR in self.params:
            del self.params[PAGE_VAR]
        if ERROR_FLAG in self.params:
            del self.params[ERROR_FLAG]

        if self.is_popup:
            self.list_editable = ()
        else:
            self.list_editable = list_editable
        self.query = request.GET.get(SEARCH_VAR, '')
        self.queryset = self.get_queryset(request)
        self.get_results(request)
        if self.is_popup:
            title = gettext('Select %s')
        else:
            title = gettext('Select %s to change')
        self.title = title % self.opts.verbose_name
        self.pk_attname = self.lookup_opts.pk.attname
Esempio n. 2
0
    def delete_view(self, request, object_id, extra_context=None):
        from django.contrib.admin.options import TO_FIELD_VAR

        to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            from django.contrib.admin.exceptions import DisallowedModelAdminToField

            raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field)

        from django.contrib.admin.utils import unquote
        user = self.get_object(request, unquote(object_id), to_field)
        tenant = user.profile.tenant if hasattr(user, 'profile') else None
        if not tenant:
            return super().delete_view(request, object_id, extra_context)
        with tenant_context(tenant):
            return super().delete_view(request, object_id, extra_context)
Esempio n. 3
0
    def change_view(self, request, object_id, form_url='', extra_context=None):
        """Отмечает запрос как прочитанный"""
        if object_id:

            to_field = request.POST.get(TO_FIELD_VAR,
                                        request.GET.get(TO_FIELD_VAR))
            if to_field and not self.to_field_allowed(request, to_field):
                raise DisallowedModelAdminToField(
                    "The field %s cannot be referenced." % to_field)

            obj = self.get_object(request, unquote(object_id), to_field)
            if obj and obj.read_status < 0:
                obj.read_status = FormRequestReadStatusEnum.READ
                obj.save()

        return super(BaseFormRequestAdmin,
                     self).change_view(request,
                                       object_id,
                                       form_url=form_url,
                                       extra_context=extra_context)
Esempio n. 4
0
def delete_view(self, request, object_id, extra_context=None):
    to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR))
    if to_field and not self.to_field_allowed(request, to_field):
        raise DisallowedModelAdminToField(
            u'The field {to_field:s} cannot be referenced.'.format(
                to_field=to_field))
    object = self.get_object(request, unquote(object_id), to_field)
    if not self.has_delete_permission(request, object):
        raise PermissionDenied
    if object is None:
        raise Http404(
            _(u'{name:} object with primary key {key:s} does not exist.').
            format(
                name=force_text(self.model._meta.verbose_name),
                key=escape(object_id),
            ))
    if request.POST:
        object_display = force_text(object)
        self.log_deletion(request, object, object_display)
        self.delete_model(request, object)
        return self.response_delete(
            request,
            object_display,
            object.serializable_value(
                str(to_field) if to_field else self.model._meta.pk.attname),
        )
    context = dict(
        self.admin_site.each_context(request),
        app_label=self.model._meta.app_label,
        is_popup=IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET,
        object=object,
        object_name=force_text(self.model._meta.verbose_name),
        opts=self.model._meta,
        preserved_filters=self.get_preserved_filters(request),
        title=_('Are you sure?'),
        to_field=to_field,
    )
    context.update(extra_context or {})
    return self.render_delete_form(request, context)
Esempio n. 5
0
    def delete_view(self, request, object_id, extra_context=None):
        "The 'delete' admin view for this model."
        opts = self.model._meta
        app_label = opts.app_label

        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

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

        if not self.has_delete_permission(request, obj):
            raise PermissionDenied

        if obj is None:
            raise Http404(
                _('%(name)s object with primary key %(key)r does not exist.') %
                {
                    'name': force_text(opts.verbose_name),
                    'key': escape(object_id)
                })

        # using = router.db_for_write(self.model)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.
        deleted_objects, model_count, perms_needed, protected = ([obj], {
            self.model.__name__:
            1
        }, [], [])

        if request.POST:  # The user has already confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = force_text(obj)
            attr = str(to_field) if to_field else opts.pk.attname
            obj_id = obj.serializable_value(attr)
            # self.log_deletion(request, obj, obj_display)
            self.delete_model(request, obj)

            return self.response_delete(request, obj_display, obj_id)

        object_name = force_text(opts.verbose_name)

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

        context = dict(
            self.admin_site.each_context(request),
            title=title,
            object_name=object_name,
            object=obj,
            deleted_objects=deleted_objects,
            model_count=dict(model_count).items(),
            perms_lacking=perms_needed,
            protected=protected,
            opts=opts,
            app_label=app_label,
            preserved_filters=self.get_preserved_filters(request),
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
        )
        context.update(extra_context or {})

        return self.render_delete_form(request, context)
Esempio n. 6
0
    def delete_view(self, request, object_id, extra_context=None):
        """
    The 'delete' admin view for this model.
    """
        opts = self.model._meta
        app_label = opts.app_label

        to_field = request.POST.get('_to_field', request.GET.get('_to_field'))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

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

        if not self.has_delete_permission(request, obj):
            raise PermissionDenied

        if obj is None:
            # Translators: Translation included with Django
            raise Http404(
                _('%(name)s object with primary key %(key)r does not exist.') %
                {
                    'name': force_text(opts.verbose_name),
                    'key': escape(object_id)
                })

        # frePPLe specific selection of the database
        using = request.database

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.
        (deleted_objects, model_count, perms_needed,
         protected) = get_deleted_objects([obj], opts, request.user,
                                          self.admin_site, using)

        # Update the links to the related objects.  frePPLe specific.
        if request.prefix:

            def replace_url(a):
                if isinstance(a, list):
                    return [replace_url(i) for i in a]
                else:
                    return mark_safe(
                        a.replace('href="', 'href="%s' % request.prefix))

            deleted_objects = [replace_url(i) for i in deleted_objects]
            protected = [replace_url(i) for i in protected]

        if request.POST:  # The user has already confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = force_text(obj)
            attr = str(to_field) if to_field else opts.pk.attname
            obj_id = obj.serializable_value(attr)
            self.log_deletion(request, obj, obj_display)
            self.delete_model(request, obj)

            return self.response_delete(request, obj_display, obj_id)

        object_name = force_text(opts.verbose_name)

        context = dict(
            self.admin_site.each_context(request),
            title=capfirst(object_name + ' ' + unquote(object_id)),
            object_name=object_name,
            object=obj,
            deleted_objects=deleted_objects,
            model_count=dict(model_count).items(),
            perms_lacking=perms_needed,
            protected=protected,
            opts=opts,
            app_label=app_label,
            preserved_filters=self.get_preserved_filters(request),
            is_popup=('_popup' in request.POST or '_popup' in request.GET),
            to_field=to_field,
        )
        context.update(extra_context or {})

        return self.render_delete_form(request, context)
Esempio n. 7
0
    def _changeform_view(self, request, object_id, form_url, extra_context):
        to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        if request.method == 'POST' and '_saveasnew' in request.POST:
            object_id = None

        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if not self.has_view_or_change_permission(request, obj):
                raise PermissionDenied

            if obj is None:
                return self._get_obj_does_not_exist_redirect(request, opts, object_id)

        ModelForm = self.get_form(request, obj, change=not add)
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            form_validated = form.is_valid()
            # on save
            if form_validated:
                new_object = self.save_form(request, form, change=not add)
            else:
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request, new_object, change=not add)
            # on update
            if all_valid(formsets) and form_validated:
                try:
                    # must not fail when there's an error getting the old object
                    old_object = new_object.__class__.objects.get(pk=new_object.pk)
                except Exception:
                    pass
                self.save_model(request, new_object, form, not add)
                self.save_related(request, form, formsets, not add)
                change_message = self.construct_change_message(request, form, formsets, add)

                if len(change_message) > 0:
                    changes = change_message[0].get('changed')
                    if changes:
                        changes['old_values'] = []
                        changes['new_values'] = []
                        changed_fields = changes['fields']
                        for changed_field in changed_fields:
                            try:
                                # when we failed to get the old object or there's an error, silently continue
                                old = getattr(old_object, changed_field)
                                new = getattr(new_object, changed_field)
                                changes['old_values'].append(str(old))
                                changes['new_values'].append(str(new))
                            except Exception:
                                pass

                if add:
                    self.log_addition(request, new_object, change_message)
                    return self.response_add(request, new_object)
                else:
                    self.log_change(request, new_object, change_message)
                    return self.response_change(request, new_object)
            else:
                form_validated = False
        else:
            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(request, form.instance, change=False)
            else:
                form = ModelForm(instance=obj)
                formsets, inline_instances = self._create_formsets(request, obj, change=True)

        if not add and not self.has_change_permission(request, obj):
            readonly_fields = flatten_fieldsets(self.get_fieldsets(request, obj))
        else:
            readonly_fields = self.get_readonly_fields(request, obj)
        adminForm = helpers.AdminForm(
            form,
            list(self.get_fieldsets(request, obj)),
            # Clear prepopulated fields on a view-only form to avoid a crash.
            self.get_prepopulated_fields(request, obj) if add or self.has_change_permission(request, obj) else {},
            readonly_fields,
            model_admin=self)
        media = self.media + adminForm.media

        inline_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        if add:
            title = _('Add %s')
        elif self.has_change_permission(request, obj):
            title = _('Change %s')
        else:
            title = _('View %s')
        context = {
            **self.admin_site.each_context(request),
            'title': title % opts.verbose_name,
            'adminform': adminForm,
            'object_id': object_id,
            'original': obj,
            'is_popup': IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET,
            'to_field': to_field,
            'media': media,
            'inline_admin_formsets': inline_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            'preserved_filters': self.get_preserved_filters(request),
        }

        # Hide the "Save" and "Save and continue" buttons if "Save as New" was
        # previously chosen to prevent the interface from getting confusing.
        if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST:
            context['show_save'] = False
            context['show_save_and_continue'] = False
            # Use the change template instead of the add template.
            add = False

        context.update(extra_context or {})

        return self.render_change_form(request, context, add=add, change=not add, obj=obj, form_url=form_url)
Esempio n. 8
0
    def _changeform_view(self, request, object_id, form_url, extra_context):
        """
        A copy of original django method with 4 tricks
        1. Calls whole_changeform_validation
        2. Calls pre_save() before saving
        3. Calls post_save() after saving
        4. emits the signal changeform_saved signal

        :param request:
        :param object_id:
        :param form_url:
        :param extra_context:
        :return:
        """
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        if request.method == 'POST' and '_saveasnew' in request.POST:
            object_id = None

        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if not self.has_view_or_change_permission(request, obj):
                raise PermissionDenied

            if obj is None:
                return self._get_obj_does_not_exist_redirect(
                    request, opts, object_id)

        ModelForm = self.get_form(request, obj, change=not add)
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            form_validated = form.is_valid()
            if form_validated:
                new_object = self.save_form(request, form, change=not add)
            else:
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request,
                                                               new_object,
                                                               change=not add)
            if all_valid(
                    formsets
            ) and form_validated and self.whole_changeform_validation(
                    request, form, formsets, not add):
                self.pre_save(form, formsets, change=not add)
                self.save_model(request, new_object, form, not add)
                self.save_related(request, form, formsets, not add)
                self.post_save(request, new_object, form, formsets, not add)
                changeform_saved.send(self.model,
                                      instance=new_object,
                                      created=add)

                change_message = self.construct_change_message(
                    request, form, formsets, add)
                if add:
                    self.log_addition(request, new_object, change_message)
                    return self.response_add(request, new_object)
                else:
                    self.log_change(request, new_object, change_message)
                    return self.response_change(request, new_object)
            else:
                form_validated = False
        else:
            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(
                    request, form.instance, change=False)
            else:
                form = ModelForm(instance=obj)
                formsets, inline_instances = self._create_formsets(request,
                                                                   obj,
                                                                   change=True)

        if not add and not self.has_change_permission(request, obj):
            readonly_fields = flatten_fieldsets(
                self.get_fieldsets(request, obj))
        else:
            readonly_fields = self.get_readonly_fields(request, obj)
        adminForm = helpers.AdminForm(
            form,
            list(self.get_fieldsets(request, obj)),
            # Clear prepopulated fields on a view-only form to avoid a crash.
            self.get_prepopulated_fields(request, obj)
            if add or self.has_change_permission(request, obj) else {},
            readonly_fields,
            model_admin=self)
        media = self.media + adminForm.media

        inline_formsets = self.get_inline_formsets(request, formsets,
                                                   inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        if add:
            title = _('Add %s')
        elif self.has_change_permission(request, obj):
            title = _('Change %s')
        else:
            title = _('View %s')
        context = {
            **self.admin_site.each_context(request),
            'title': title % opts.verbose_name,
            'adminform': adminForm,
            'object_id': object_id,
            'original': obj,
            'is_popup': IS_POPUP_VAR in request.POST
            or IS_POPUP_VAR in request.GET,
            'to_field': to_field,
            'media': media,
            'inline_admin_formsets': inline_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            'preserved_filters': self.get_preserved_filters(request),
        }

        # Hide the "Save" and "Save and continue" buttons if "Save as New" was
        # previously chosen to prevent the interface from getting confusing.
        if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST:
            context['show_save'] = False
            context['show_save_and_continue'] = False
            # Use the change template instead of the add template.
            add = False

        context.update(extra_context or {})

        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)
Esempio n. 9
0
    def _delete_view(self, request, object_id, extra_context):
        "The 'delete' admin view for this model."
        opts = self.model._meta
        app_label = opts.app_label

        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

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

        if not self.has_delete_permission(request, obj):
            raise PermissionDenied

        if obj is None:
            return self._get_obj_does_not_exist_redirect(
                request, opts, object_id)

        using = router.db_for_write(self.model)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.
        (deleted_objects, model_count, perms_needed,
         protected) = get_deleted_objects([obj], opts, request.user,
                                          self.admin_site, using)

        if request.POST and not protected:  # The user has confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = force_text(obj)
            attr = str(to_field) if to_field else opts.pk.attname
            obj_id = obj.serializable_value(attr)

            response = self.do_deleting(request, obj, obj_display, obj_id)
            if response:
                return response

            model_form = self.get_form(request, obj)

            form = model_form(instance=obj)
            formsets, inline_instances = self._create_formsets(request,
                                                               obj,
                                                               change=True)

            admin_form = helpers.AdminForm(
                form,
                list(self.get_fieldsets(request, obj)),
                self.get_prepopulated_fields(request, obj),
                self.get_readonly_fields(request, obj),
                model_admin=self)
            media = self.media + admin_form.media

            inline_formsets = self.get_inline_formsets(request, formsets,
                                                       inline_instances, obj)
            for inline_formset in inline_formsets:
                media = media + inline_formset.media

            context = dict(
                self.admin_site.each_context(request),
                title=(_('Change %s')) % force_text(opts.verbose_name),
                adminform=admin_form,
                object_id=object_id,
                original=obj,
                is_popup=(IS_POPUP_VAR in request.POST
                          or IS_POPUP_VAR in request.GET),
                to_field=to_field,
                media=media,
                inline_admin_formsets=inline_formsets,
                errors=helpers.AdminErrorList(form, formsets),
                preserved_filters=self.get_preserved_filters(request),
            )
            return self.render_change_form(request,
                                           context,
                                           add=False,
                                           change=True,
                                           obj=obj,
                                           form_url='')

        object_name = force_text(opts.verbose_name)

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

        context = dict(
            self.admin_site.each_context(request),
            title=title,
            object_name=object_name,
            object=obj,
            deleted_objects=deleted_objects,
            model_count=dict(model_count).items(),
            perms_lacking=perms_needed,
            protected=protected,
            opts=opts,
            app_label=app_label,
            preserved_filters=self.get_preserved_filters(request),
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
        )
        context.update(extra_context or {})

        return self.render_delete_form(request, context)
Esempio n. 10
0
    def _changeform_view(self, request, object_id, form_url, extra_context):
        """
        I know overriding such a long method is terrible! But I do not know what a better
        approach would be. I will take a look at this patch method to try to patch all_valid().
        https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch
        """
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        if request.method == 'POST' and '_saveasnew' in request.POST:
            object_id = None

        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if request.method == 'POST':
                if not self.has_change_permission(request, obj):
                    raise PermissionDenied
            else:
                if not self.has_view_or_change_permission(request, obj):
                    raise PermissionDenied

            if obj is None:
                return self._get_obj_does_not_exist_redirect(
                    request, opts, object_id)

        fieldsets = self.get_fieldsets(request, obj)
        ModelForm = self.get_form(request,
                                  obj,
                                  change=not add,
                                  fields=flatten_fieldsets(fieldsets))
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            form_validated = form.is_valid()
            if form_validated:
                new_object = self.save_form(request, form, change=not add)
            else:
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request,
                                                               new_object,
                                                               change=not add)
            if self.all_valid(form, formsets) and form_validated:
                self.save_model(request, new_object, form, not add)
                self.save_related(request, form, formsets, not add)
                change_message = self.construct_change_message(
                    request, form, formsets, add)
                if add:
                    self.log_addition(request, new_object, change_message)
                    return self.response_add(request, new_object)
                else:
                    self.log_change(request, new_object, change_message)
                    return self.response_change(request, new_object)
            else:
                form_validated = False
        else:
            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(
                    request, form.instance, change=False)
            else:
                form = ModelForm(instance=obj)
                formsets, inline_instances = self._create_formsets(request,
                                                                   obj,
                                                                   change=True)

        if not add and not self.has_change_permission(request, obj):
            readonly_fields = flatten_fieldsets(fieldsets)
        else:
            readonly_fields = self.get_readonly_fields(request, obj)
        adminForm = helpers.AdminForm(
            form,
            list(fieldsets),
            # Clear prepopulated fields on a view-only form to avoid a crash.
            self.get_prepopulated_fields(request, obj)
            if add or self.has_change_permission(request, obj) else {},
            readonly_fields,
            model_admin=self)
        media = self.media + adminForm.media

        inline_formsets = self.get_inline_formsets(request, formsets,
                                                   inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        if add:
            title = _('Add %s')
        elif self.has_change_permission(request, obj):
            title = _('Change %s')
        else:
            title = _('View %s')
        context = {
            **self.admin_site.each_context(request),
            'title': title % opts.verbose_name,
            'subtitle': str(obj) if obj else None,
            'adminform': adminForm,
            'object_id': object_id,
            'original': obj,
            'is_popup': IS_POPUP_VAR in request.POST
            or IS_POPUP_VAR in request.GET,
            'to_field': to_field,
            'media': media,
            'inline_admin_formsets': inline_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            'preserved_filters': self.get_preserved_filters(request),
        }

        # Hide the "Save" and "Save and continue" buttons if "Save as New" was
        # previously chosen to prevent the interface from getting confusing.
        if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST:
            context['show_save'] = False
            context['show_save_and_continue'] = False
            # Use the change template instead of the add template.
            add = False

        context.update(extra_context or {})

        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)
Esempio n. 11
0
    def _change_confirmation_view(self, request, object_id, form_url, extra_context):  # noqa: C901
        to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field
            )

        model = self.model
        opts = model._meta

        add = object_id is None
        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied

            obj = None
        else:
            obj = self.get_object(request, unquote(object_id), to_field)
            if obj is None:
                return self._get_obj_does_not_exist_redirect(request, opts, object_id)

            if not self.has_view_or_change_permission(request, obj):
                raise PermissionDenied

        ModelForm = self.get_form(request, obj=obj, change=not add)
        is_agent_initial = obj.is_agent

        form = ModelForm(request.POST, request.FILES, instance=obj)
        form_validated = form.is_valid()
        new_object = self.save_form(request, form, change=not add) if form_validated else form.instance

        is_agent_disabled = False
        if form_validated:
            is_agent_changed = form.fields['is_agent'].has_changed(
                is_agent_initial, new_object.is_agent) if 'is_agent' in form.fields else False
            is_agent_disabled = is_agent_changed and not new_object.is_agent

        is_confirm_required = bool(is_agent_disabled and new_object.user_schedules.exists())

        if not is_confirm_required:
            return super()._changeform_view(request, object_id, form_url, extra_context)

        # Parse raw form data from POST
        form_data = {}
        # Parse the original save action from request
        save_action = None
        for key in request.POST:
            if key in ["_save", "_saveasnew", "_addanother", "_continue"]:
                save_action = key

            if key.startswith("_") or key == "csrfmiddlewaretoken":
                continue
            form_data[key] = request.POST.get(key)
        context = {
            **self.admin_site.each_context(request),
            "preserved_filters": self.get_preserved_filters(request),
            "title": _('Confirm user change'),
            "subtitle": str(obj),
            "object_name": str(obj),
            "object_id": object_id,
            "app_label": opts.app_label,
            "model_name": opts.model_name,
            "opts": opts,
            "form_data": form_data,
            "add": add,
            "submit_name": save_action,
            **(extra_context or {}),
        }
        return self.render_change_confirmation(request, context)
Esempio n. 12
0
    def changeform_view(self,
                        request,
                        object_id=None,
                        form_url='',
                        extra_context=None):
        """
        This follows closely the base implementation from Django 1.7's
        django.contrib.admin.options.ModelAdmin,
        with the explicitly marked modifications.
        """
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta
        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

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

            if not self.has_change_permission(request, obj):
                raise PermissionDenied

            if obj is None:
                raise Http404(
                    _('%(name)s object with primary key %(key)r does not exist.'
                      ) % {
                          'name': force_text(opts.verbose_name),
                          'key': escape(object_id)
                      })

            if request.method == 'POST' and "_saveasnew" in request.POST:
                return self.add_view(
                    request,
                    form_url=reverse('admin:%s_%s_add' %
                                     (opts.app_label, opts.model_name),
                                     current_app=self.admin_site.name))

        #### begin modification ####
        # make sure that the user has a full session length time for the current
        # edit activity
        request.session.set_expiry(settings.SESSION_COOKIE_AGE)
        #### end modification ####

        ModelForm = self.get_form(request, obj)
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            if form.is_valid():
                form_validated = True
                new_object = self.save_form(request, form, change=not add)
            else:
                form_validated = False
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request,
                                                               new_object,
                                                               change=not add)
            if all_valid(formsets) and form_validated:
                #### begin modification ####
                unsaved_formsets = []
                for formset in formsets:
                    parent_fk_name = getattr(formset, 'parent_fk_name', '')
                    # for the moment ignore all formsets that are no reverse
                    # inlines
                    if add:
                        if not parent_fk_name:
                            unsaved_formsets.append(formset)
                            continue

                    # this replaces the call to self.save_formsets()
                    changes = formset.save()
                    # if there are any changes in the current inline and if this
                    # inline is a reverse inline, then we need to manually make
                    # sure that the inline data is connected to the parent
                    # object:
                    if changes:
                        if parent_fk_name:
                            assert len(changes) == 1
                            setattr(new_object, parent_fk_name, changes[0])

                    # If we have deleted a one-to-one inline, we must manually
                    # unset the field value.
                    if formset.deleted_objects:
                        if parent_fk_name:
                            setattr(new_object, parent_fk_name, None)

                self.save_model(request, new_object, form, not add)
                form.save_m2m()

                for formset in unsaved_formsets:
                    self.save_formset(request, form, formset, add)

                # for resource info, explicitly write its metadata XML and
                # storage object to the storage folder
                if self.model.__schema_name__ == "resourceInfo":
                    new_object.storage_object.update_storage()
                #### end modification ####
                if add:
                    self.log_addition(request, new_object)
                    return self.response_add(request, new_object)
                else:
                    change_message = self.construct_change_message(
                        request, form, formsets)
                    self.log_change(request, new_object, change_message)
                    return self.response_change(request, new_object)
        else:
            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(
                    request, self.model(), change=False)
            else:
                form = ModelForm(instance=obj)
                formsets, inline_instances = self._create_formsets(request,
                                                                   obj,
                                                                   change=True)

        #### begin modification ####
        media = self.media or []
        #### end modification ####

        inline_formsets = self.get_inline_formsets(request, formsets,
                                                   inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        #### begin modification ####
        adminForm = OrderedAdminForm(
            form,
            list(self.get_fieldsets_with_inlines(request)),
            self.prepopulated_fields,
            self.get_readonly_fields(request, obj),
            model_admin=self,
            inlines=inline_formsets)
        media = media + adminForm.media
        #### end modification ####

        context = dict(self.admin_site.each_context(),
            title=(_('Add %s') if add else _('Change %s')) % force_text(opts.verbose_name),
            adminform=adminForm,
            object_id=object_id,
            original=obj,
            is_popup=(IS_POPUP_VAR in request.REQUEST or \
                      IS_POPUP_O2M_VAR in request.REQUEST),
            to_field=to_field,
            media=media,
            inline_admin_formsets=inline_formsets,
            errors=helpers.AdminErrorList(form, formsets),
            preserved_filters=self.get_preserved_filters(request),
            kb_link=settings.KNOWLEDGE_BASE_URL,
            app_label=opts.app_label,
            show_delete=False,
        )

        context.update(extra_context or {})

        #### begin modification ####
        if not add:
            # redirection for reusable entities which are no master copies:
            if hasattr(obj, 'copy_status') and obj.copy_status != MASTER:
                context['url'] = obj.source_url
                context_instance = template.RequestContext(
                    request, current_app=self.admin_site.name)
                return render_to_response('admin/repository/cannot_edit.html',
                                          context,
                                          context_instance=context_instance)
            # redirection for resources and their parts which are no master copies:
            else:
                for res in [
                        r for r in get_root_resources(obj)
                        if not r.storage_object.master_copy
                ]:
                    context['redirection_url'] = model_utils.get_lr_master_url(
                        res)
                    context['resource'] = res
                    context_instance = template.RequestContext(
                        request, current_app=self.admin_site.name)
                    return render_to_response(
                        'admin/repository/cannot_edit.html',
                        context,
                        context_instance=context_instance)
        #### end modification ####
        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)
Esempio n. 13
0
    def reset_view(self, request, object_id, extra_context=None):
        # based on ModelAdmin.delete_view, slightly modified to delete obj.questions.answers.all() instead of obj
        with transaction.atomic(using=router.db_for_write(self.model)):
            opts = self.model._meta
            app_label = opts.app_label

            to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR))
            if to_field and not self.to_field_allowed(request, to_field):
                raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field)

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

            if obj is None:
                return self._get_obj_does_not_exist_redirect(request, opts, object_id)

            # Populate deleted_objects, a data structure of all related objects that
            # will also be deleted.
            qs = FormQuestionAnswer.objects.filter(question__form=obj).prefetch_related('question', 'question__form', 'user')
            deleted_objects, model_count, perms_needed, protected = self.get_deleted_objects(qs, request)

            if request.POST and not protected:  # The user has confirmed the deletion.
                if perms_needed:
                    raise PermissionDenied
                obj_display = str(obj)
                attr = str(to_field) if to_field else opts.pk.attname
                obj_id = obj.serializable_value(attr)

                qs.delete()

                self.message_user(
                    request,
                    _('The %(name)s “%(obj)s” was deleted successfully.') % {
                        'name': 'odpowiedzi do wszystkich pytań z formularza',
                        'obj': obj_display,
                    },
                    messages.SUCCESS,
                )

                if self.has_change_permission(request, None):
                    post_url = reverse(
                        'admin:%s_%s_change' % (opts.app_label, opts.model_name),
                        args=[obj_id],
                        current_app=self.admin_site.name,
                    )
                else:
                    post_url = reverse('admin:index', current_app=self.admin_site.name)
                return HttpResponseRedirect(post_url)

            if perms_needed or protected:
                title = _("Cannot delete %(name)s") % {"name": 'odpowiedzi do wszystkich pytań z formularza'}
            else:
                title = _("Are you sure?")

            context = {
                **self.admin_site.each_context(request),
                'title': title,
                'object_name': 'wszystkie odpowiedzi do wszystkich pytań z formularza',
                'object': obj,
                'deleted_objects': deleted_objects,
                'model_count': dict(model_count).items(),
                'perms_lacking': perms_needed,
                'protected': protected,
                'opts': opts,
                'app_label': app_label,
                'preserved_filters': self.get_preserved_filters(request),
                'is_popup': IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET,
                'to_field': to_field,
                **(extra_context or {}),
            }

            return self.render_delete_form(request, context)
Esempio n. 14
0
    def _change_confirmation_view(self, request, object_id, form_url,
                                  extra_context):
        # This code is taken from super()._changeform_view
        # https://github.com/django/django/blob/master/django/contrib/admin/options.py#L1575-L1592
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        if SAVE_AS_NEW in request.POST:
            object_id = None

        add = object_id is None
        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied

            obj = None
        else:
            obj = self.get_object(request, unquote(object_id), to_field)
            if obj is None:
                return self._get_obj_does_not_exist_redirect(
                    request, opts, object_id)

            if not self.has_view_or_change_permission(request, obj):
                raise PermissionDenied

        fieldsets = self.get_fieldsets(request, obj)
        ModelForm = self.get_form(request,
                                  obj,
                                  change=not add,
                                  fields=flatten_fieldsets(fieldsets))

        form = ModelForm(request.POST, request.FILES, instance=obj)
        form_validated = form.is_valid()
        if form_validated:
            new_object = self.save_form(request, form, change=not add)
        else:
            new_object = form.instance
        formsets, inline_instances = self._create_formsets(request,
                                                           new_object,
                                                           change=not add)
        # End code from super()._changeform_view
        # form.is_valid() checks both errors and "is_bound"
        # If form has errors, show the errors on the form instead of showing confirmation page
        if not form_validated:
            log("Invalid Form: return early")
            log(form.errors)
            # We must ensure that we ask for confirmation when showing errors
            extra_context = self._add_confirmation_options_to_extra_context(
                extra_context)
            return super()._changeform_view(request, object_id, form_url,
                                            extra_context)

        add_or_new = add or SAVE_AS_NEW in request.POST
        # Get changed data to show on confirmation
        changed_data = self._get_changed_data(form, model, obj, add_or_new)

        changed_confirmation_fields = set(
            self.get_confirmation_fields(request, obj)) & set(
                changed_data.keys())
        if not bool(changed_confirmation_fields):
            log("No change detected")
            # No confirmation required for changed fields, continue to save
            return super()._changeform_view(request, object_id, form_url,
                                            extra_context)

        # Parse the original save action from request
        save_action = None
        # No cover: There would not be a case of not request.POST.keys() and form is valid
        for key in request.POST.keys():  # pragma: no cover
            if key in SAVE_ACTIONS:
                save_action = key
                break

        cleared_fields = []
        if form.is_multipart():
            log("Caching files")
            cache.set(CACHE_KEYS["object"], new_object, CACHE_TIMEOUT)

            # Save files as tempfiles
            for field_name in request.FILES:
                file = request.FILES[field_name]
                self._file_cache.set(
                    format_cache_key(model=model.__name__, field=field_name),
                    file)

            # Handle when files are cleared - since the `form` object would not hold that info
            cleared_fields = self._get_cleared_fields(request)

        log("Render Change Confirmation")
        title_action = _("adding") if add_or_new else _("changing")
        context = {
            **self.admin_site.each_context(request),
            "preserved_filters":
            self.get_preserved_filters(request),
            "title":
            f"{_('Confirm')} {title_action} {opts.verbose_name}",
            "subtitle":
            str(obj),
            "object_name":
            str(obj),
            "object_id":
            object_id,
            "app_label":
            opts.app_label,
            "model_name":
            opts.model_name,
            "opts":
            opts,
            "changed_data":
            changed_data,
            "add":
            add,
            "save_as_new":
            SAVE_AS_NEW in request.POST,
            "submit_name":
            save_action,
            "form":
            form,
            "cleared_fields":
            cleared_fields,
            "formsets":
            formsets,
            **(extra_context or {}),
        }
        return self.render_change_confirmation(request, context)
Esempio n. 15
0
    def changeform_view(self,
                        request,
                        object_id=None,
                        form_url='',
                        extra_context=None):
        """
        This follows closely the base implementation from Django 1.7's
        django.contrib.admin.options.ModelAdmin with the explicitly marked
        modifications.
        """
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta
        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

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

            if not self.has_change_permission(request, obj):
                raise PermissionDenied

            if obj is None:
                raise Http404(
                    _('%(name)s object with primary key %(key)r does not exist.'
                      ) % {
                          'name': force_text(opts.verbose_name),
                          'key': escape(object_id)
                      })

            if request.method == 'POST' and "_saveasnew" in request.POST:
                return self.add_view(
                    request,
                    form_url=reverse('admin:%s_%s_add' %
                                     (opts.app_label, opts.model_name),
                                     current_app=self.admin_site.name))

        #### begin modification ####
        # make sure that the user has a full session length time for the current
        # edit activity
        request.session.set_expiry(settings.SESSION_COOKIE_AGE)
        #### end modification ####

        ModelForm = self.get_form(request, obj)
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            if form.is_valid():
                form_validated = True
                new_object = self.save_form(request, form, change=not add)
            else:
                form_validated = False
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request,
                                                               new_object,
                                                               change=not add)
            if all_valid(formsets) and form_validated:
                self.save_model(request, new_object, form, not add)
                self.save_related(request, form, formsets, not add)
                if add:
                    self.log_addition(request, new_object)
                    return self.response_add(request, new_object)
                else:
                    change_message = self.construct_change_message(
                        request, form, formsets)
                    self.log_change(request, new_object, change_message)
                    return self.response_change(request, new_object)
        else:
            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(
                    request, self.model(), change=False)
            else:
                form = ModelForm(instance=obj)
                formsets, inline_instances = self._create_formsets(request,
                                                                   obj,
                                                                   change=True)

        adminForm = helpers.AdminForm(form,
                                      list(self.get_fieldsets(request, obj)),
                                      self.get_prepopulated_fields(
                                          request, obj),
                                      self.get_readonly_fields(request, obj),
                                      model_admin=self)
        media = self.media + adminForm.media

        inline_formsets = self.get_inline_formsets(request, formsets,
                                                   inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        context = dict(self.admin_site.each_context(),
            title=(_('Add %s') if add else _('Change %s')) % force_text(opts.verbose_name),
            adminform=adminForm,
            object_id=object_id,
            original=obj,
            is_popup=(IS_POPUP_VAR in request.REQUEST or \
                      IS_POPUP_O2M_VAR in request.REQUEST),
            to_field=to_field,
            media=media,
            inline_admin_formsets=inline_formsets,
            errors=helpers.AdminErrorList(form, formsets),
            preserved_filters=self.get_preserved_filters(request),
            kb_link=settings.KNOWLEDGE_BASE_URL,
            app_label=opts.app_label,
            show_delete=False,
        )

        context.update(extra_context or {})
        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)
Esempio n. 16
0
    def changeform_view(self,
                        request,
                        object_id=None,
                        form_url='',
                        extra_context=None):

        base_model = self.model.get_base_model()

        content_type = request.POST.get(
            'target_type', request.GET.get('target_type', None)) or None
        content_type = ContentType.objects.filter(id=content_type).first()

        parent_id = request.POST.get(
            'target_page', request.GET.get('target_page', None)) or None
        parent = base_model.objects.filter(id=parent_id).first()
        parent = parent.specific if parent else None

        msg, url = None, None
        if not object_id:
            if not content_type:
                url = '%s?target_type=%s' % (
                    self.get_admin_url_for_model(base_model, 'prepare'),
                    ContentType.objects.get_for_model(self.model).id)
            elif not issubclass(content_type.model_class(), base_model):
                msg = _('ContentType "%s" is not subclass of base Page.'
                        ' It should be one of Page classes.') % content_type
                url = self.get_admin_url_for_model(base_model, 'prepare')
            elif content_type.model_class() is not self.model:
                msg = _('Page type "%s" does not match admin model class'
                        ' "%s".') % (
                            content_type,
                            self.model.__name__,
                        )
                url = '%s?target_type=%s' % (self.get_admin_url_for_model(
                    base_model, 'prepare'), content_type.id)
            elif parent_id and not parent:
                msg = _('Invalid "target_page" value, page does not exist.')
                url = '%s?target_type=%s' % (self.get_admin_url_for_model(
                    base_model, 'prepare'), content_type.id)
            elif parent and not self.model.can_create_at(parent):
                msg = _('Page type "%s" can not be created in "%s" parent'
                        ' page.') % (
                            self.model.__name__,
                            parent,
                        )
                url = '%s?target_type=%s' % (self.get_admin_url_for_model(
                    base_model, 'prepare'), content_type.id)
            elif not content_type.model_class().is_creatable:
                msg = _('Page type "%s" can not be created manually'
                        ' in admin interface.') % content_type
                url = self.get_admin_url_for_model(base_model, 'prepare')
            elif (self.model.max_count
                  and self.model.objects.count() >= self.model.max_count):
                msg = _('Page type "%s" exceeded max_count instances limit'
                        ' (%d).') % (
                            self.model.__name__,
                            self.model.max_count,
                        )
                url = self.get_admin_url_for_model(base_model, 'prepare')
        else:
            to_field = request.POST.get(TO_FIELD_VAR,
                                        request.GET.get(TO_FIELD_VAR))
            if to_field and not self.to_field_allowed(request, to_field):
                raise DisallowedModelAdminToField(
                    "The field %s can not be referenced." % to_field)

            # redirect if concrete type of obj and admin model do not match
            obj = self.get_object(request, unquote(object_id), to_field)
            obj = obj.specific if obj else None
            if obj and type(obj) is not self.model:
                url = '%s?_changelist_filters=e%%3D%s' % (
                    self.get_admin_url_for_model(
                        type(obj), 'change', args=(quote(
                            obj.pk), )), ERROR_VALUE_FOR_REDIRECT)

        if msg:
            self.message_user(request, msg, messages.ERROR)
        if url:
            return redirect(url)

        return super().changeform_view(request,
                                       object_id=object_id,
                                       form_url=form_url,
                                       extra_context=extra_context)
Esempio n. 17
0
    def __init__(
        self,
        request,
        model,
        list_display,
        list_display_links,
        list_filter,
        date_hierarchy,
        search_fields,
        list_select_related,
        list_per_page,
        list_max_show_all,
        list_editable,
        model_admin,
        sortable_by,
        search_help_text,
    ):
        self.model = model
        self.opts = model._meta
        self.lookup_opts = self.opts
        self.root_queryset = model_admin.get_queryset(request)
        self.list_display = list_display
        self.list_display_links = list_display_links
        self.list_filter = list_filter
        self.has_filters = None
        self.has_active_filters = None
        self.clear_all_filters_qs = None
        self.date_hierarchy = date_hierarchy
        self.search_fields = search_fields
        self.list_select_related = list_select_related
        self.list_per_page = list_per_page
        self.list_max_show_all = list_max_show_all
        self.model_admin = model_admin
        self.preserved_filters = model_admin.get_preserved_filters(request)
        self.sortable_by = sortable_by
        self.search_help_text = search_help_text

        # Get search parameters from the query string.
        _search_form = self.search_form_class(request.GET)
        if not _search_form.is_valid():
            for error in _search_form.errors.values():
                messages.error(request, ", ".join(error))
        self.query = _search_form.cleaned_data.get(SEARCH_VAR) or ""
        try:
            self.page_num = int(request.GET.get(PAGE_VAR, 1))
        except ValueError:
            self.page_num = 1
        self.show_all = ALL_VAR in request.GET
        self.is_popup = IS_POPUP_VAR in request.GET
        to_field = request.GET.get(TO_FIELD_VAR)
        if to_field and not model_admin.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field
            )
        self.to_field = to_field
        self.params = dict(request.GET.items())
        if PAGE_VAR in self.params:
            del self.params[PAGE_VAR]
        if ERROR_FLAG in self.params:
            del self.params[ERROR_FLAG]

        if self.is_popup:
            self.list_editable = ()
        else:
            self.list_editable = list_editable
        self.queryset = self.get_queryset(request)
        self.get_results(request)
        if self.is_popup:
            title = gettext("Select %s")
        elif self.model_admin.has_change_permission(request):
            title = gettext("Select %s to change")
        else:
            title = gettext("Select %s to view")
        self.title = title % self.opts.verbose_name
        self.pk_attname = self.lookup_opts.pk.attname
Esempio n. 18
0
    def bulk_view(self, request, form_url='', extra_context=None):
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        continue_requested = request.POST.get('_continue',
                                              request.GET.get('_continue'))
        force_continue = False
        inline = self.get_bulk_inline(request)
        formset_class = inline.get_formset(request)
        formset_params = {}
        prefix = formset_class.get_default_prefix()
        queryset = inline.get_queryset(request)

        if not self.has_add_permission(request):
            formset_class.max_num = 0

        if request.method == 'GET':
            if 'pks' in request.GET and self.has_change_permission(request):
                pks = [
                    opts.pk.to_python(pk)
                    for pk in request.GET.get('pks').split(',')
                ]
                queryset = queryset.filter(pk__in=pks)
            else:
                queryset = queryset.none()

        elif request.method == 'POST':
            management_form = ManagementForm(request.POST, prefix=prefix)

            if not management_form.is_valid():
                raise ValidationError(
                    _('ManagementForm data is missing or has been tampered with'
                      ),
                    code='missing_management_form',
                )

            if not self.has_add_permission(
                    request) and management_form.cleaned_data[
                        INITIAL_FORM_COUNT] < management_form.cleaned_data[
                            TOTAL_FORM_COUNT]:
                raise PermissionDenied

            if not self.has_change_permission(
                    request
            ) and management_form.cleaned_data[INITIAL_FORM_COUNT] > 0:
                raise PermissionDenied

            queryset = self.transform_queryset(request, queryset,
                                               management_form, prefix)

            post, files, force_continue = self.transform_post_and_files(
                request, prefix)
            formset_params.update({
                'data': post,
                'files': files,
            })

        formset_params['queryset'] = queryset

        formset = formset_class(**formset_params)

        if request.method == 'POST':
            if formset.is_valid():
                self.save_formset(request,
                                  form=None,
                                  formset=formset,
                                  change=False)

                if continue_requested or force_continue:
                    # The implementation of ModelAdmin redirects to the change view if valid and continue was requested
                    # The change view then reads the edited model again from database
                    # In our case, we can't make a redirect as we would loose the information which models should be edited
                    # Thus, we create a new formset with the edited models and continue as this would have been a usual GET request

                    if self.has_change_permission(request):
                        queryset = _ListQueryset(queryset)
                        queryset.extend(formset.new_objects)
                    else:
                        queryset = _ListQueryset()

                    formset_params.update({
                        'data': None,
                        'files': None,
                        'queryset': queryset,
                    })

                    formset = formset_class(**formset_params)

                    msg = _(
                        'The %s were bulk added successfully. You may edit them again below.'
                    ) % (force_text(opts.verbose_name_plural), )
                    self.message_user(request, msg, messages.SUCCESS)

                else:
                    return self.response_bulk(request, formset)

        media = self.media

        inline_formsets = self.get_inline_formsets(request, [formset],
                                                   [inline],
                                                   obj=None)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        errors = ErrorList()

        if formset.is_bound:
            errors.extend(formset.non_form_errors())
            for formset_errors in formset.errors:
                errors.extend(list(six.itervalues(formset_errors)))

        print("type(inline_formsets)")
        print(type(inline_formsets))
        print(inline_formsets)
        print(*inline_formsets, sep=", ")
        print("request")
        print(type(request))
        print(request)
        context = dict(
            self.admin_site.each_context(request) if django.VERSION >=
            (1, 8) else self.admin_site.each_context(),
            bulk=True,
            bulk_formset_prefix=prefix,
            bulk_upload_fields=self.get_bulk_upload_fields(request),
            title=_('Bulk add %s') % force_text(opts.verbose_name_plural),
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
            media=media,
            inline_admin_formsets=inline_formsets,
            errors=errors,
            preserved_filters=self.get_preserved_filters(request),
            # adminform=inline_formsets,
            # adminform=super(BulkModelAdmin, self).get_form(request, **kwargs) #kwargs not define
            # adminform=super(BulkModelAdmin, self).get_form(request) #object 'ContainerForm' has no attribute 'form'
            # searching for ContainerForm gives me nothing
            #writing a dummy form - uses models
            # adminform=DummyModelForm
            # but that ModelForm has no modelclass, nothing in models.py
        )

        context.update(extra_context or {})

        # print(context)

        return self.render_change_form(request,
                                       context,
                                       add=True,
                                       change=False,
                                       obj=None,
                                       form_url=form_url)
Esempio n. 19
0
    def _delete_view(self, request, object_id, extra_context):

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

        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

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

        if not self.has_delete_permission(request, obj):
            raise PermissionDenied

        if obj is None:
            return self._get_obj_does_not_exist_redirect(
                request, opts, object_id)

        using = router.db_for_write(self.model)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.
        (deleted_objects, model_count, perms_needed,
         protected) = get_deleted_objects([obj], opts, request.user,
                                          self.admin_site, using)

        if request.POST and not protected:  # The user has confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = force_text(obj)
            attr = str(to_field) if to_field else opts.pk.attname
            course_id = obj.course.id
            obj_id = obj.serializable_value(attr)
            self.log_deletion(request, obj, obj_display)
            self.delete_model(request, obj)

            return self.response_delete(request, obj_display, obj_id,
                                        course_id)

        object_name = force_text(opts.verbose_name)

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

        context = dict(
            self.admin_site.each_context(request),
            title=title,
            object_name=object_name,
            object=obj,
            deleted_objects=deleted_objects,
            model_count=dict(model_count).items(),
            perms_lacking=perms_needed,
            protected=protected,
            opts=opts,
            app_label=app_label,
            preserved_filters=self.get_preserved_filters(request),
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
        )
        context.update(extra_context or {})

        return self.render_delete_form(request, context)
Esempio n. 20
0
    def changeform_view(self,
                        request,
                        object_id=None,
                        form_url='',
                        extra_context=None):
        """
        Overriding the changeform view of ModelAdmin to allow the form view to be displayed
        when the user only has view permissions.
        In this case, the form view will be displayed in readonly mode and without action buttons
        """
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta
        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if not self.has_change_permission(
                    request, obj) and not self.has_view_permission(
                        request, obj):
                raise PermissionDenied

            if obj is None:
                raise Http404(
                    _('%(name)s object with primary key %(key)r does not exist.'
                      ) % {
                          'name': force_text(opts.verbose_name),
                          'key': escape(object_id)
                      })

            if request.method == 'POST' and "_saveasnew" in request.POST:
                return self.add_view(
                    request,
                    form_url=reverse('admin:%s_%s_add' %
                                     (opts.app_label, opts.model_name),
                                     current_app=self.admin_site.name))

        ModelForm = self.get_form(request, obj)
        # do not save the change if I'm not allowed to:
        if request.method == 'POST' and self.has_change_permission(
                request, obj):
            form = ModelForm(request.POST, request.FILES, instance=obj)
            if form.is_valid():
                form_validated = True
                new_object = self.save_form(request, form, change=not add)
            else:
                form_validated = False
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request,
                                                               new_object,
                                                               change=not add)
            if all_valid(formsets) and form_validated:
                self.save_model(request, new_object, form, not add)
                self.save_related(request, form, formsets, not add)
                if add:
                    self.log_addition(request, new_object)
                    return self.response_add(request, new_object)
                else:
                    change_message = self.construct_change_message(
                        request, form, formsets)
                    self.log_change(request, new_object, change_message)
                    return self.response_change(request, new_object)
        else:
            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(
                    request, self.model(), change=False)
            else:
                form = ModelForm(instance=obj)
                formsets, inline_instances = self._create_formsets(request,
                                                                   obj,
                                                                   change=True)

        adminForm = helpers.AdminForm(form,
                                      list(self.get_fieldsets(request, obj)),
                                      self.get_prepopulated_fields(
                                          request, obj),
                                      self.get_readonly_fields(request, obj),
                                      model_admin=self)
        media = self.media + adminForm.media

        inline_formsets = self.get_inline_formsets(request, formsets,
                                                   inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        context = dict(
            self.admin_site.each_context(request),
            title=(_('Add %s') if add else _('Change %s')) %
            force_text(opts.verbose_name),
            adminform=adminForm,
            object_id=object_id,
            original=obj,
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
            media=media,
            inline_admin_formsets=inline_formsets,
            errors=helpers.AdminErrorList(form, formsets),
            preserved_filters=self.get_preserved_filters(request),
        )

        context.update(extra_context or {})

        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)
Esempio n. 21
0
    def view_view(self, request, object_id, form_url='', extra_context=None):
        extra_context = extra_context or {}
        extra_context['has_add_permission'] = self.has_add_permission(request)
        '''
            Code copied from ChangeForm
        '''

        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta
        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if not self.has_view_permission(request, obj):
                raise PermissionDenied

            if obj is None:
                raise Http404(
                    _('%(name)s object with primary key %(key)r does not exist.'
                      ) % {
                          'name': force_text(opts.verbose_name),
                          'key': escape(object_id)
                      })

                # if request.method == 'POST' and "_saveasnew" in request.POST:
                #     return self.add_view(request, form_url=reverse('admin:%s_%s_add' % (
                #         opts.app_label, opts.model_name), current_app=self.admin_site.name))
        context = dict(
            self.admin_site.each_context(request),
            title=obj,
            app_label=opts.app_label,
            object_id=object_id,
            original=obj,
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
            # media=media,
            preserved_filters=self.get_preserved_filters(request),
        )

        context.update(extra_context or {})

        opts = self.model._meta
        app_label = opts.app_label
        preserved_filters = self.get_preserved_filters(request)
        form_url = add_preserved_filters(
            {
                'preserved_filters': preserved_filters,
                'opts': opts
            }, form_url)
        view_on_site_url = self.get_view_on_site_url(obj)
        context.update({
            'add':
            add,
            'change':
            not add,
            'has_add_permission':
            self.has_add_permission(request),
            'has_change_permission':
            self.has_change_permission(request, obj),
            'has_delete_permission':
            self.has_delete_permission(request, obj),
            'has_file_field':
            True,
            'has_absolute_url':
            view_on_site_url is not None,
            'absolute_url':
            view_on_site_url,
            'form_url':
            form_url,
            'opts':
            opts,
            'content_type_id':
            get_content_type_for_model(self.model).pk,
            'save_as':
            self.save_as,
            'save_on_top':
            self.save_on_top,
            'to_field_var':
            TO_FIELD_VAR,
            'is_popup_var':
            IS_POPUP_VAR,
            'app_label':
            app_label,
        })

        request.current_app = self.admin_site.name
        return TemplateResponse(
            request, self.view_template or [
                "admin/%s/%s/view.html" % (opts.app_label, opts.model_name),
                "admin/%s/view.html" % opts.app_label,
                f"{app_settings.RA_THEME}/view.html",
            ], context)
Esempio n. 22
0
    def bulk_view(self, request, form_url='', extra_context=None):
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        continue_requested = request.POST.get('_continue',
                                              request.GET.get('_continue'))
        force_continue = False
        inline = self.get_bulk_inline(request)
        formset_class = inline.get_formset(request)
        formset_params = {}
        prefix = formset_class.get_default_prefix()
        queryset = inline.get_queryset(request)

        if not self.has_add_permission(request):
            formset_class.max_num = 0

        if request.method == 'GET':
            if 'pks' in request.GET and self.has_change_permission(request):
                pks = [
                    opts.pk.to_python(pk)
                    for pk in request.GET.get('pks').split(',')
                ]
                queryset = queryset.filter(pk__in=pks)
            else:
                queryset = queryset.none()

        elif request.method == 'POST':
            management_form = ManagementForm(request.POST, prefix=prefix)

            if not management_form.is_valid():
                raise ValidationError(
                    _('ManagementForm data is missing or has been tampered with'
                      ),
                    code='missing_management_form',
                )

            if not self.has_add_permission(
                    request) and management_form.cleaned_data[
                        INITIAL_FORM_COUNT] < management_form.cleaned_data[
                            TOTAL_FORM_COUNT]:
                raise PermissionDenied

            if not self.has_change_permission(
                    request
            ) and management_form.cleaned_data[INITIAL_FORM_COUNT] > 0:
                raise PermissionDenied

            queryset = self.transform_queryset(request, queryset,
                                               management_form, prefix)

            post, files, force_continue = self.transform_post_and_files(
                request, prefix)
            formset_params.update({
                'data': post,
                'files': files,
            })

        formset_params['queryset'] = queryset

        formset = formset_class(**formset_params)

        if request.method == 'POST':
            if formset.is_valid():
                self.save_formset(request,
                                  form=None,
                                  formset=formset,
                                  change=False)

                if continue_requested or force_continue:
                    # The implementation of ModelAdmin redirects to the change view if valid and continue was requested
                    # The change view then reads the edited model again from database
                    # In our case, we can't make a redirect as we would loose the information which models should be edited
                    # Thus, we create a new formset with the edited models and continue as this would have been a usual GET request

                    if self.has_change_permission(request):
                        queryset = _ListQueryset(queryset)
                        queryset.extend(formset.new_objects)
                    else:
                        queryset = _ListQueryset()

                    formset_params.update({
                        'data': None,
                        'files': None,
                        'queryset': queryset,
                    })

                    formset = formset_class(**formset_params)

                    msg = _(
                        'The %s were bulk added successfully. You may edit them again below.'
                    ) % (force_text(opts.verbose_name_plural), )
                    self.message_user(request, msg, messages.SUCCESS)

                else:
                    return self.response_bulk(request, formset)

        media = self.media

        inline_formsets = self.get_inline_formsets(request, [formset],
                                                   [inline],
                                                   obj=None)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        errors = ErrorList()

        if formset.is_bound:
            errors.extend(formset.non_form_errors())
            for formset_errors in formset.errors:
                errors.extend(list(iter(formset_errors.values())))

        context = self.admin_site.each_context(request)
        context.update({
            'bulk':
            True,
            'bulk_formset_prefix':
            prefix,
            'bulk_upload_fields':
            self.get_bulk_upload_fields(request),
            'title':
            _('Bulk add %s') % force_text(opts.verbose_name_plural),
            'is_popup': (IS_POPUP_VAR in request.POST
                         or IS_POPUP_VAR in request.GET),
            'to_field':
            to_field,
            'media':
            media,
            'inline_admin_formsets':
            inline_formsets,
            'errors':
            errors,
            'preserved_filters':
            self.get_preserved_filters(request),
            'adminform':
            admin.helpers.AdminForm(ManagementForm(), [], {}),
        })
        context.update(extra_context or {})

        return self.render_change_form(request,
                                       context,
                                       add=True,
                                       change=False,
                                       obj=None,
                                       form_url=form_url)
Esempio n. 23
0
    def _changeform_view(self, request, object_id, form_url, extra_context):

        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        if request.method == 'POST' and '_saveasnew' in request.POST:
            object_id = None

        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if not self.has_change_permission(request, obj):
                raise PermissionDenied

            if obj is None:
                return self._get_obj_does_not_exist_redirect(
                    request, opts, object_id)

        ModelForm = self.get_form(request, obj)
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            if form.is_valid():
                form_validated = True
                new_object = self.save_form(request, form, change=not add)
            else:
                form_validated = False
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request,
                                                               new_object,
                                                               change=not add)
            if all_valid(formsets) and form_validated:
                self.save_model(request, new_object, form, not add)
                self.save_related(request, form, formsets, not add)
                change_message = self.construct_change_message(
                    request, form, formsets, add)
                if add:
                    self.log_addition(request, new_object, change_message)
                    return self.response_add(request, new_object)
                else:
                    self.log_change(request, new_object, change_message)
                    return self.response_change(request, new_object)
            else:
                form_validated = False
        else:
            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(
                    request, form.instance, change=False)
            else:
                form = ModelForm(instance=obj, initial=self.choice_field_value)
                formsets, inline_instances = self._create_formsets(request,
                                                                   obj,
                                                                   change=True)

        adminForm = helpers.AdminForm(form,
                                      list(self.get_fieldsets(request, obj)),
                                      self.get_prepopulated_fields(
                                          request, obj),
                                      self.get_readonly_fields(request, obj),
                                      model_admin=self)
        media = self.media + adminForm.media

        inline_formsets = self.get_inline_formsets(request, formsets,
                                                   inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        context = dict(
            self.admin_site.each_context(request),
            title=(_('Add %s') if add else _('Change %s')) % opts.verbose_name,
            adminform=adminForm,
            object_id=object_id,
            original=obj,
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
            media=media,
            inline_admin_formsets=inline_formsets,
            errors=helpers.AdminErrorList(form, formsets),
            preserved_filters=self.get_preserved_filters(request),
        )

        # Hide the "Save" and "Save and continue" buttons if "Save as New" was
        # previously chosen to prevent the interface from getting confusing.
        if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST:
            context['show_save'] = False
            context['show_save_and_continue'] = False
            # Use the change template instead of the add template.
            add = False

        context.update(extra_context or {})

        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)
Esempio n. 24
0
    def changeform_view(self,
                        request,
                        object_id=None,
                        form_url='',
                        extra_context=None):
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        if request.method == 'POST' and '_saveasnew' in request.POST:
            object_id = None

        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if not self.has_change_permission(request, obj):
                raise PermissionDenied

            if obj is None:
                raise Http404(
                    _('%(name)s object with primary key %(key)r does not exist.'
                      ) % {
                          'name': force_text(opts.verbose_name),
                          'key': escape(object_id)
                      })

        form = SimpleJSONForm()
        if request.method == 'POST':
            form = SimpleJSONForm(request.POST, instance=obj)
            if form.is_valid():
                form_validated = True
                form.save(self.model)
            else:
                form_validated = False
        else:
            if obj:
                form = SimpleJSONForm(instance=obj)
            else:
                form = SimpleJSONForm()

        adminForm = helpers.AdminForm(
            form,
            form.get_fieldsets(),  #list(self.get_fieldsets(request, obj)),
            {},  #self.get_prepopulated_fields(request, obj),
            [],  #[self.get_readonly_fields(request, obj)],
            model_admin=self)
        media = self.media + adminForm.media

        context = dict(
            self.admin_site.each_context(request),
            title=(_('Add %s') if add else _('Change %s')) %
            force_text(opts.verbose_name),
            adminform=adminForm,
            object_id=object_id,
            original=obj,
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
            media=media,
            errors=helpers.AdminErrorList(form, []),
            preserved_filters=self.get_preserved_filters(request),
        )

        # Hide the "Save" and "Save and continue" buttons if "Save as New" was
        # previously chosen to prevent the interface from getting confusing.
        if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST:
            context['show_save'] = False
            context['show_save_and_continue'] = False
            # Use the change template instead of the add template.
            add = False

        context.update(extra_context or {})

        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)
Esempio n. 25
0
    def delete_view(self, request, object_id, extra_context=None):
        """
        This method overrides the 'delete' admin view.
        Changes include handling exceptions raised while deleting a model and
        displaying the exception message to the user in a readable format instead of
        showing the exception page to the user
        """
        opts = self.model._meta
        app_label = opts.app_label

        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

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

        if not self.has_delete_permission(request, obj):
            raise PermissionDenied

        if obj is None:
            raise Http404(
                _('%(name)s object with primary key %(key)r does not exist.') %
                {
                    'name': force_text(opts.verbose_name),
                    'key': escape(object_id)
                })

        using = router.db_for_write(self.model)

        # Populate deleted_objects, a data structure of all related objects that
        # will also be deleted.
        (deleted_objects, model_count, perms_needed,
         protected) = get_deleted_objects([obj], opts, request.user,
                                          self.admin_site, using)

        if request.POST:  # The user has already confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = force_text(obj)
            attr = str(to_field) if to_field else opts.pk.attname
            obj_id = obj.serializable_value(attr)

            # start: base changes
            try:
                self.delete_model(request, obj)
            except Exception as e:
                return self.response_delete(request,
                                            obj_display,
                                            obj_id,
                                            msg=e.message,
                                            msg_type=messages.ERROR)

            self.log_deletion(request, obj, obj_display)
            # end: base changes

            return self.response_delete(request, obj_display, obj_id)

        object_name = force_text(opts.verbose_name)

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

        context = dict(
            self.admin_site.each_context(request),
            title=title,
            object_name=object_name,
            object=obj,
            deleted_objects=deleted_objects,
            model_count=dict(model_count).items(),
            perms_lacking=perms_needed,
            protected=protected,
            opts=opts,
            app_label=app_label,
            preserved_filters=self.get_preserved_filters(request),
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
        )
        context.update(extra_context or {})

        return self.render_delete_form(request, context)
Esempio n. 26
0
    def _changeform_view(self, request, object_id, form_url,
                         extra_context):  # noqa
        """
        Based on https://github.com/django/django/blob/2.2.17/django/contrib/admin/options.py#L1531
        The creation of the materialized view needed to happen on background
        """
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                f"The field {to_field} cannot be referenced.")

        opts = self.model._meta

        if request.method == "POST" and "_saveasnew" in request.POST:
            object_id = None

        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if request.method == "POST":
                if not self.has_change_permission(request, obj):
                    raise PermissionDenied
            else:
                if not self.has_view_or_change_permission(request, obj):
                    raise PermissionDenied

            if obj is None:
                return self._get_obj_does_not_exist_redirect(
                    request, opts, object_id)

        ModelForm = self.get_form(request, obj, change=not add)
        if request.method == "POST":
            obj_dict = obj.to_dict() if obj else None
            form = ModelForm(request.POST, request.FILES, instance=obj)
            form_validated = form.is_valid()
            if form_validated:
                new_object = self.save_form(request, form, change=not add)
            else:
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request,
                                                               new_object,
                                                               change=not add)
            if all_valid(formsets) and form_validated:
                self.background_task = create_materialized_view.delay(
                    request.user.pk,
                    obj_dict,
                    serializers.serialize("json", [new_object]),
                    self.construct_change_message(request, form, formsets,
                                                  add),
                )
                if add:
                    return self.response_add(request, new_object)
                return self.response_change(request, new_object)
        else:
            if add:
                form = ModelForm(
                    initial=self.get_changeform_initial_data(request))
                formsets, inline_instances = self._create_formsets(
                    request, form.instance, change=False)
            else:
                form = ModelForm(instance=obj)
                formsets, inline_instances = self._create_formsets(request,
                                                                   obj,
                                                                   change=True)

        if not add and not self.has_change_permission(request, obj):
            readonly_fields = flatten_fieldsets(
                self.get_fieldsets(request, obj))
        else:
            readonly_fields = self.get_readonly_fields(request, obj)
        adminForm = helpers.AdminForm(
            form,
            list(self.get_fieldsets(request, obj)),
            # Clear prepopulated fields on a view-only form to avoid a crash.
            self.get_prepopulated_fields(request, obj)
            if add or self.has_change_permission(request, obj) else {},
            readonly_fields,
            model_admin=self,
        )
        media = self.media + adminForm.media

        inline_formsets = self.get_inline_formsets(request, formsets,
                                                   inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        if add:
            title = _("Add %s")
        elif self.has_change_permission(request, obj):
            title = _("Change %s")
        else:
            title = _("View %s")
        context = {
            **self.admin_site.each_context(request),
            "title": title % opts.verbose_name,
            "adminform": adminForm,
            "object_id": object_id,
            "original": obj,
            "is_popup": IS_POPUP_VAR in request.POST
            or IS_POPUP_VAR in request.GET,
            "to_field": to_field,
            "media": media,
            "inline_admin_formsets": inline_formsets,
            "errors": helpers.AdminErrorList(form, formsets),
            "preserved_filters": self.get_preserved_filters(request),
            "show_save_and_continue": False,
        }

        context.update(extra_context or {})

        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)
Esempio n. 27
0
    def _delete_view(self, request, object_id, extra_context):
        """
        The 'delete' admin view for this model.
        """
        opts = self.model._meta
        app_label = opts.app_label

        to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field
            )

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

        if not self.has_delete_permission(request, obj):
            raise PermissionDenied

        if obj is None:
            return self._get_obj_does_not_exist_redirect(request, opts, object_id)

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

        # frePPLe specific: Update the links to the related objects.
        if request.prefix:

            def replace_url(a):
                if isinstance(a, list):
                    return [replace_url(i) for i in a]
                else:
                    return mark_safe(a.replace('href="', 'href="%s' % request.prefix))

            deleted_objects = [replace_url(i) for i in deleted_objects]
            protected = [replace_url(i) for i in protected]

        if request.POST and not protected:  # The user has confirmed the deletion.
            if perms_needed:
                raise PermissionDenied
            obj_display = str(obj)
            attr = str(to_field) if to_field else opts.pk.attname
            obj_id = obj.serializable_value(attr)
            self.log_deletion(request, obj, obj_display)
            self.delete_model(request, obj)

            return self.response_delete(request, obj_display, obj_id)

        object_name = str(opts.verbose_name)

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

        context = {
            **self.admin_site.each_context(request),
            "title": title,
            "object_name": object_name,
            "object": obj,
            "object_id": obj,
            "deleted_objects": deleted_objects,
            "model_count": dict(model_count).items(),
            "perms_lacking": perms_needed,
            "protected": protected,
            "opts": opts,
            "app_label": app_label,
            "preserved_filters": self.get_preserved_filters(request),
            "is_popup": (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET),
            "to_field": to_field,
            **(extra_context or {}),
        }

        return self.render_delete_form(request, context)
Esempio n. 28
0
    def changeform_view(self,
                        request,
                        object_id=None,
                        form_url='',
                        extra_context=None):
        contents = None
        to_field = request.POST.get(TO_FIELD_VAR,
                                    request.GET.get(TO_FIELD_VAR))
        if to_field and not self.to_field_allowed(request, to_field):
            raise DisallowedModelAdminToField(
                "The field %s cannot be referenced." % to_field)

        model = self.model
        opts = model._meta

        if request.method == 'POST' and '_saveasnew' in request.POST:
            object_id = None

        add = object_id is None

        if add:
            if not self.has_add_permission(request):
                raise PermissionDenied
            obj = None

        else:
            obj = self.get_object(request, unquote(object_id), to_field)

            if not self.has_change_permission(request, obj):
                raise PermissionDenied

            if obj is None:
                raise Http404(
                    _('%(name)s object with primary key %(key)r does not exist.'
                      ) % {
                          'name': force_text(opts.verbose_name),
                          'key': escape(object_id)
                      })

        ModelForm = self.get_form(request, obj)
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES, instance=obj)
            contents = []
            all_content_forms_valid = True
            if obj and obj.contents:
                for content in obj.contents.all():
                    content = content.polymorph()
                    content.build_admin_form(request.POST, request.FILES)
                    if not content.is_admin_form_valid():
                        all_content_forms_valid = False
                    contents.append(content)
            if form.is_valid() and all_content_forms_valid:
                form_validated = True
                new_object = self.save_form(request, form, change=not add)
                for content in contents:
                    content.save_admin_form(request)
            else:
                form_validated = False
                new_object = form.instance
            formsets, inline_instances = self._create_formsets(request,
                                                               new_object,
                                                               change=not add)
            if all_valid(formsets) and form_validated:
                self.save_model(request, new_object, form, not add)
                self.save_related(request, form, formsets, not add)
                change_message = self.construct_change_message(
                    request, form, formsets, add)
                if add:
                    self.log_addition(request, new_object, change_message)
                    return self.response_add(request, new_object)
                else:
                    self.log_change(request, new_object, change_message)
                    return self.response_change(request, new_object)
            else:
                form_validated = False
        else:
            all_content_forms_valid = True
            if add:
                initial = self.get_changeform_initial_data(request)
                form = ModelForm(initial=initial)
                formsets, inline_instances = self._create_formsets(
                    request, form.instance, change=False)
            else:
                form = ModelForm(instance=obj)
                contents = []
                if obj.contents:
                    for content in obj.contents.all():
                        content = content.polymorph()
                        content.build_admin_form()
                        contents.append(content)
                formsets, inline_instances = self._create_formsets(request,
                                                                   obj,
                                                                   change=True)

        adminForm = helpers.AdminForm(form,
                                      list(self.get_fieldsets(request, obj)),
                                      self.get_prepopulated_fields(
                                          request, obj),
                                      self.get_readonly_fields(request, obj),
                                      model_admin=self)
        media = self.media + adminForm.media

        inline_formsets = self.get_inline_formsets(request, formsets,
                                                   inline_instances, obj)
        for inline_formset in inline_formsets:
            media = media + inline_formset.media

        context = dict(
            self.admin_site.each_context(request),
            title=(_('Add %s') if add else _('Change %s')) %
            force_text(opts.verbose_name),
            adminform=adminForm,
            object_id=object_id,
            original=obj,
            is_popup=(IS_POPUP_VAR in request.POST
                      or IS_POPUP_VAR in request.GET),
            to_field=to_field,
            media=media,
            inline_admin_formsets=inline_formsets,
            errors=helpers.AdminErrorList(form, formsets)
            or not all_content_forms_valid,
            preserved_filters=self.get_preserved_filters(request),
            contents=contents,
            copy_url_name='admin:' + self.model._meta.model_name + '_copy',
            copy_supported=hasattr(obj, 'copy'),
            change_form_extend_template=self.change_form_extend_template,
            show_xprez_toolbar=self._show_xprez_toolbar(request, object_id))

        # Hide the "Save" and "Save and continue" buttons if "Save as New" was
        # previously chosen to prevent the interface from getting confusing.
        if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST:
            context['show_save'] = False
            context['show_save_and_continue'] = False
            # Use the change template instead of the add template.
            add = False

        context.update(extra_context or {})

        return self.render_change_form(request,
                                       context,
                                       add=add,
                                       change=not add,
                                       obj=obj,
                                       form_url=form_url)