@csrf_protect_m
    @atomic_decorator
    def change_view(self, request, object_id, extra_context=None, **kwargs):
        model = self.model
        opts = model._meta
        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_unicode(opts.verbose_name), 'key': escape(object_id)})

        if request.method == 'POST' and "_saveasnew" in request.POST:
            return self.add_view(request, form_url='../add/')

        ModelForm = self.get_form(request, obj)
        formsets = []

        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=True)
            else:
                form_validated = False
                new_object = obj

            prefixes = {}

            for FormSet, inline in zip(self.get_formsets(request, new_object),
                                       self.get_inline_instances(request)):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1

                if prefixes[prefix] != 1:
                    prefix = "{0}-{1}".format(prefix, prefixes[prefix])
                formset = FormSet(request.POST, request.FILES,
                                  instance=new_object, prefix=prefix,
                                  queryset=inline.queryset(request))

                formsets.append(formset)

                for inline in self.get_inline_instances(request):
                    # If this is the inline that matches this formset, and
                    # we have some nested inlines to deal with, then we need
                    # to get the relevant formset for each of the forms in
                    # the current formset.
                    if inline.inlines and inline.model == formset.model:
                        for nested in inline.inline_instances:
                            for the_form in formset.forms:
                                InlineFormSet = nested.get_formset(request, the_form.instance)
                                prefix = "{0}-{1}".format(the_form.prefix,
                                                          InlineFormSet.get_default_prefix())
                                formsets.append(InlineFormSet(request.POST, request.FILES,
                                                              instance=the_form.instance,
                                                              prefix=prefix))
            if all_valid(formsets) and form_validated:
                self.save_model(request, new_object, form, change=True)
                form.save_m2m()

                for formset in formsets:
                    self.save_formset(request, form, formset, change=True)

                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:
            form = ModelForm(instance=obj)
            prefixes = {}

            for FormSet, inline in zip(self.get_formsets(request, obj),
                                       self.get_inline_instances(request)):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1:
                    prefix = "{0}-{1}".format(prefix, prefixes[prefix])
                formset = FormSet(instance=obj, prefix=prefix,
                                  queryset=inline.queryset(request))
                formsets.append(formset)

        adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj),
                                      self.prepopulated_fields,
                                      self.get_readonly_fields(request, obj),
                                      model_admin=self)
        media = self.media + adminForm.media
        inline_admin_formsets = []

        for inline, formset in zip(self.get_inline_instances(request), formsets):
            fieldsets = list(inline.get_fieldsets(request, obj))
            readonly = list(inline.get_readonly_fields(request, obj))
            inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets,
                                                              readonly, model_admin=self)
            if inline.inlines:
                for form in formset.forms:
                    if form.instance.pk:
                        instance = form.instance
                    else:
                        instance = None

                    form.inlines = inline.get_inlines(request, instance, prefix=form.prefix)

                inline_admin_formset.inlines = inline.get_inlines(request)

            inline_admin_formsets.append(inline_admin_formset)
            media = media + inline_admin_formset.media

        context = {
            'title': _('Change %s') % force_unicode(opts.verbose_name),
            'adminform': adminForm,
            'object_id': object_id,
            'original': obj,
            'is_popup': "_popup" in request.REQUEST,
            'media': mark_safe(media),
            'inline_admin_formsets': inline_admin_formsets,
            'errors': helpers.AdminErrorList(form, formsets),
            'app_label': opts.app_label,
        }

        context.update(extra_context or {})

        return self.render_change_form(request, context, change=True, obj=obj)
The 'change' admin view for this model.
dataset/ETHPy150Open Tivix/django-common/django_common/admin.py/NestedModelAdmin.change_view