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

File 00-admin-better-saving.diff, 11.0 KB (added by Petr Marhoun <petr.marhoun@…>, 8 years ago)
  • django/contrib/admin/options.py

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