Ticket #6002: 00-admin-better-saving.2.diff

File 00-admin-better-saving.2.diff, 11.1 KB (added by Petr Marhoun <petr.marhoun@…>, 7 years ago)

new version - after autoescape merge

  • django/contrib/admin/options.py

    === modified file 'django/contrib/admin/options.py'
     
    354354            fields = None
    355355        return forms.form_for_instance(obj, fields=fields, formfield_callback=self.formfield_for_dbfield)
    356356
    357     def save_add(self, request, model, form, formsets, post_url_continue):
    358         """
    359         Saves the object in the "add" stage and returns an HttpResponseRedirect.
    360 
    361         `form` is a bound Form instance that's verified to be valid.
    362         """
     357    def save(self, request, form, formsets, original_obj, commit=True):
     358        """ Save new or changed object and its inlines. """
     359        new_obj = form.save(commit=commit)
     360        for formset in formsets:
     361            # HACK: it seems like the parent object should be passed into
     362            # a method of something, not just set as an attribute
     363            formset.instance = new_obj
     364            formset.save()
     365        return new_obj
     366
     367    def save_add(self, request, form, formsets, commit=True):
     368        """ Save new object and its inlines. """
     369        return self.save(request, form, formsets, None, commit)
     370
     371    def save_change(self, request, form, formsets, original_obj, commit=True):
     372        """ Save changed object and its inlines. """
     373        return self.save(request, form, formsets, original_obj, commit)
     374
     375    def log_add(self, request, form, formsets, new_obj):
     376        """ Log saving of new object and its inlines. """
    363377        from django.contrib.admin.models import LogEntry, ADDITION
    364         from django.contrib.contenttypes.models import ContentType
    365         opts = model._meta
    366         new_object = form.save(commit=True)
    367 
    368         if formsets:
    369             for formset in formsets:
    370                 # HACK: it seems like the parent obejct should be passed into
    371                 # a method of something, not just set as an attribute
    372                 formset.instance = new_object
    373                 formset.save()
    374 
    375         pk_value = new_object._get_pk_val()
    376         LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, force_unicode(new_object), ADDITION)
    377         msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_object}
    378         # Here, we distinguish between different save types by checking for
    379         # the presence of keys in request.POST.
    380         if request.POST.has_key("_continue"):
    381             request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
    382             if request.POST.has_key("_popup"):
    383                 post_url_continue += "?_popup=1"
    384             return HttpResponseRedirect(post_url_continue % pk_value)
    385         if request.POST.has_key("_popup"):
    386             if type(pk_value) is str: # Quote if string, so JavaScript doesn't think it's a variable.
    387                 pk_value = '"%s"' % pk_value.replace('"', '\\"')
    388             return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
    389                 # escape() calls force_unicode.
    390                 (escape(pk_value), escape(new_object)))
    391         elif request.POST.has_key("_addanother"):
    392             request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
    393             return HttpResponseRedirect(request.path)
    394         else:
    395             request.user.message_set.create(message=msg)
    396             # Figure out where to redirect. If the user has change permission,
    397             # redirect to the change-list page for this object. Otherwise,
    398             # redirect to the admin index.
    399             if self.has_change_permission(request, None):
    400                 post_url = '../'
    401             else:
    402                 post_url = '../../../'
    403             return HttpResponseRedirect(post_url)
    404 
    405     def save_change(self, request, model, form, formsets=None):
    406         """
    407         Saves the object in the "change" stage and returns an HttpResponseRedirect.
    408 
    409         `form` is a bound Form instance that's verified to be valid.
    410        
    411         `formsets` is a sequence of InlineFormSet instances that are verified to be valid.
    412         """
     378        user_id = request.user.id
     379        content_type_id = ContentType.objects.get_for_model(self.model).id
     380        object_id = new_obj._get_pk_val()
     381        LogEntry.objects.log_action(user_id, content_type_id, object_id, force_unicode(new_obj), ADDITION)
     382
     383    def log_change(self, request, form, formsets, original_obj, new_obj):
     384        """ Log saving of changed object and its inlines. """
    413385        from django.contrib.admin.models import LogEntry, CHANGE
    414         from django.contrib.contenttypes.models import ContentType
    415         opts = model._meta
    416         new_object = form.save(commit=True)
    417         pk_value = new_object._get_pk_val()
    418 
    419         if formsets:
    420             for formset in formsets:
    421                 formset.save()
    422 
     386        user_id = request.user.id
     387        content_type_id = ContentType.objects.get_for_model(self.model).id
     388        object_id = new_obj._get_pk_val()
    423389        # Construct the change message. TODO: Temporarily commented-out,
    424390        # as manipulator object doesn't exist anymore, and we don't yet
    425391        # have a way to get fields_added, fields_changed, fields_deleted.
     
    433399        #change_message = ' '.join(change_message)
    434400        if not change_message:
    435401            change_message = _('No fields changed.')
    436         LogEntry.objects.log_action(request.user.id, ContentType.objects.get_for_model(model).id, pk_value, force_unicode(new_object), CHANGE, change_message)
    437 
    438         msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_object}
    439         if request.POST.has_key("_continue"):
    440             request.user.message_set.create(message=msg + ' ' + _("You may edit it again below."))
    441             if request.REQUEST.has_key('_popup'):
    442                 return HttpResponseRedirect(request.path + "?_popup=1")
    443             else:
    444                 return HttpResponseRedirect(request.path)
    445         elif request.POST.has_key("_saveasnew"):
    446             request.user.message_set.create(message=_('The %(name)s "%(obj)s" was added successfully. You may edit it again below.') % {'name': opts.verbose_name, 'obj': new_object})
    447             return HttpResponseRedirect("../%s/" % pk_value)
    448         elif request.POST.has_key("_addanother"):
    449             request.user.message_set.create(message=msg + ' ' + (_("You may add another %s below.") % opts.verbose_name))
    450             return HttpResponseRedirect("../add/")
    451         else:
    452             request.user.message_set.create(message=msg)
    453             return HttpResponseRedirect("../")
     402        LogEntry.objects.log_action(user_id, content_type_id, object_id, force_unicode(new_obj), CHANGE, change_message)
     403
     404    def redirect_after_save(self, request, new_obj, add=False, change=False):
     405        """ Redirect after saving of new or changed object. """
     406        opts = self.opts
     407        pk_value = new_obj._get_pk_val()
     408
     409        # popup
     410        if request.POST.has_key('_popup'):
     411            if isinstance(pk_value, str): # Quote if string, so JavaScript doesn't think it's a variable.
     412                pk_value = '"%s"' % pk_value.replace('"', '\\"')
     413            return HttpResponse('<script type="text/javascript">opener.dismissAddAnotherPopup(window, %s, "%s");</script>' % \
     414                # escape() calls force_unicode.
     415                (escape(pk_value), escape(new_obj)))
     416
     417        # default message       
     418        if add:
     419            msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': opts.verbose_name, 'obj': new_obj}
     420        else:
     421            msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': opts.verbose_name, 'obj': new_obj}
     422
     423        # save as new
     424        if request.POST.has_key('_saveasnew'):
     425            if self.has_change_permission(request, new_obj):
     426                msg += ' ' + _('You may edit it again below.')
     427                redirect_url = '../%s/' % pk_value
     428            elif self.has_change_permission(request, None):
     429                redirect_url = '../'
     430            else:
     431                redirect_url = '../../../'
     432        # save and add another
     433        elif request.POST.has_key('_addanother'):
     434            msg += ' ' + (_('You may add another %s below.') % opts.verbose_name)
     435            if add:
     436                redirect_url = request.path
     437            else:
     438                redirect_url = '../add/'
     439        # save and continue editing
     440        elif request.POST.has_key('_continue'):
     441            if self.has_change_permission(request, new_obj):
     442                msg += ' ' + _('You may edit it again below.')
     443                if add:
     444                    redirect_url = '../%s/' % pk_value
     445                else:
     446                    redirect_url = request.path
     447            elif self.has_change_permission(request, None):
     448                redirect_url = '../'
     449            else:
     450                redirect_url = '../../../'
     451        # save
     452        else:
     453            if self.has_change_permission(request, None):
     454                redirect_url = '../'
     455            else:
     456                redirect_url = '../../../'
     457
     458        # create message and redirect
     459        request.user.message_set.create(message=msg)
     460        return HttpResponseRedirect(redirect_url)
    454461
    455462    def render_change_form(self, model, context, add=False, change=False, form_url=''):
    456463        opts = model._meta
     
    484491        if not self.has_add_permission(request):
    485492            raise PermissionDenied
    486493
    487         if self.has_change_permission(request, None):
    488             # redirect to list view
    489             post_url = '../'
    490         else:
    491             # Object list will give 'Permission Denied', so go back to admin home
    492             post_url = '../../../'
    493 
    494494        ModelForm = self.form_add(request)
    495495        inline_formsets = []
    496496        if request.method == 'POST':
     
    499499                inline_formset = FormSet(data=request.POST, files=request.FILES)
    500500                inline_formsets.append(inline_formset)
    501501            if all_valid(inline_formsets) and form.is_valid():
    502                 return self.save_add(request, model, form, inline_formsets, '../%s/')
     502                new_obj = self.save_add(request, form, inline_formsets)
     503                self.log_add(request, form, inline_formsets, new_obj)
     504                return self.redirect_after_save(request, new_obj, add=True)
    503505        else:
    504506            form = ModelForm(initial=request.GET)
    505507            for FormSet in self.formsets_add(request):
     
    559561                inline_formsets.append(inline_formset)
    560562
    561563            if all_valid(inline_formsets) and form.is_valid():
    562                 return self.save_change(request, model, form, inline_formsets)
     564                new_obj = self.save_change(request, form, inline_formsets, obj)
     565                self.log_change(request, form, inline_formsets, obj, new_obj)
     566                return self.redirect_after_save(request, new_obj, change=True)
    563567        else:
    564568            form = ModelForm()
    565569            for FormSet in self.formsets_change(request, obj):
Back to Top