Exemplo n.º 1
0
 def clean_username(self):
     """Username must be unique."""
     username = self.cleaned_data['username']
     username_taken = User.object.filter(username=username).exist
     if username_taken:
         raise forms.all_valid('Username is already in use')
     return username
Exemplo n.º 2
0
    def post(self, request, *args, **kwargs):

        modelform = self.get_modelform()
        inlines_formsets = self.get_inlines_formsets()

        if modelform.is_valid():
            formsets = [formset for inline, formset in inlines_formsets]
            if forms.all_valid(formsets):
                return self.form_valid(modelform, formsets)
        return self.form_invalid(modelform, inlines_formsets)
Exemplo n.º 3
0
    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        form_class = self.get_form_class()
        form = self.get_form(form_class)

        inlines = self.get_inlines()

        if form.is_valid() and all_valid(inline.formset for inline in inlines):
            return self.form_valid(form, inlines)

        return self.form_invalid(form, inlines)
Exemplo n.º 4
0
    def post(self, request, *args, **kwargs):
        self.object = None
        form_class = self.get_form_class()
        form = self.get_form(form_class)

        if form.is_valid():
            # we have to make sure that the same instance is used for form and inlines
            inlines = self.get_inlines(object=form.save(commit=False))
        else:
            inlines = self.get_inlines()

        if all_valid(inline.formset for inline in inlines) and form.is_valid():
            return self.form_valid(form, inlines)

        return self.form_invalid(form, inlines)
Exemplo n.º 5
0
    def log_form_addition_or_change(self, form, was_adding, formsets=None):
        """
        Shortcut for logging the addition/deletion made via form. Resembles ModelAdmin too.
        If there are accompanyed formset to the main action, their change could be logged too.
        """
        if not form.is_valid():
            raise ValidationError("Form invalid.")
        if formsets and not all_valid(formsets):
            raise ValidationError("Some of the formsets not valid.")

        message_list = construct_change_message(form, formsets, was_adding)

        if was_adding:
            self.log_addition(form.instance, message_list)
        else:
            self.log_change(form.instance, message_list)
Exemplo n.º 6
0
 def is_valid(self, check_forms: typing.Dict[CheckId, "typing.Type[BaseCheckForm]"]) -> bool:  # type: ignore
     if not super().is_valid():
         return False
     checks = self.cleaned_data.get("checks", {})
     rforms = {
         name: check_forms[name](data=value)
         for name, value in checks.items()
         if name in check_forms
     }
     if forms.all_valid(rforms.values()):  # type: ignore
         self.cleaned_data["checks"] = {
             name: f.cleaned_data for name, f in rforms.items()
         }
         return True
     self.errors["checks"] = {name: form.errors for name, form in rforms.items()}
     return False
Exemplo n.º 7
0
def article_form(request):
    context = {}
    if request.method == 'POST':
        article = ArticleForm(request.POST)
        picture_forms = Pictureformset(request.POST, request.FILES)
        article_instance = ""
        if article.is_valid():
            article_instance = article.save()
        if all_valid(picture_forms):
            for pictureform in picture_forms:
                picture = pictureform.save(commit=False)
                picture.article = article_instance
                picture.save()
    context["form"] = ArticleForm()
    context["formset"] = Pictureformset()
    return render(request, "article_form.html", context)
Exemplo 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)
Exemplo n.º 9
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)
Exemplo n.º 10
0
 def is_valid(self):
     is_valid = super(AdditionalFormsMixin, self).is_valid()
     if len(self.extra_forms) > 0:
         return is_valid and all_valid(self.extra_forms)
     else:
         return is_valid
Exemplo n.º 11
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)
Exemplo n.º 12
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)