Ticket #13223: 13223.newview-prototype.diff

File 13223.newview-prototype.diff, 8.9 KB (added by Igor Sobreira, 12 years ago)

Prototype for an intermediate clone/ view

  • django/contrib/admin/options.py

    diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
    index f5f6256..1a0ec54 100644
    a b from django import forms  
    33from django.conf import settings
    44from django.forms.formsets import all_valid
    55from django.forms.models import (modelform_factory, modelformset_factory,
    6     inlineformset_factory, BaseInlineFormSet)
     6    inlineformset_factory, BaseInlineFormSet, model_to_dict)
    77from django.contrib.contenttypes.models import ContentType
    88from django.contrib.admin import widgets, helpers
    99from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_objects, model_format_dict
    class ModelAdmin(BaseModelAdmin):  
    383383            url(r'^(.+)/delete/$',
    384384                wrap(self.delete_view),
    385385                name='%s_%s_delete' % info),
     386            url(r'^(.+)/clone/$',
     387                wrap(self.clone_view),
     388                name='%s_%s_clone' % info),
    386389            url(r'^(.+)/$',
    387390                wrap(self.change_view),
    388391                name='%s_%s_change' % info),
    class ModelAdmin(BaseModelAdmin):  
    950953                    prefix = "%s-%s" % (prefix, prefixes[prefix])
    951954                formset = FormSet(data=request.POST, files=request.FILES,
    952955                                  instance=new_object,
    953                                   save_as_new="_saveasnew" in request.POST,
    954956                                  prefix=prefix, queryset=inline.queryset(request))
    955957                formsets.append(formset)
    956958            if all_valid(formsets) and form_validated:
    class ModelAdmin(BaseModelAdmin):  
    10091011        context.update(extra_context or {})
    10101012        return self.render_change_form(request, context, form_url=form_url, add=True)
    10111013
     1014
     1015    @csrf_protect_m
     1016    @transaction.commit_on_success
     1017    def clone_view(self, request, object_id, form_url='', extra_context=None):
     1018        model = self.model
     1019        opts = model._meta
     1020
     1021        if not self.has_add_permission(request):
     1022            raise PermissionDenied
     1023
     1024        original_obj = self.get_object(request, unquote(object_id))
     1025
     1026        ModelForm = self.get_form(request)
     1027        formsets = []
     1028        inline_instances = self.get_inline_instances(request)
     1029        if request.method == 'POST':
     1030            form = ModelForm(request.POST, request.FILES)
     1031            if form.is_valid():
     1032                new_object = self.save_form(request, form, change=False)
     1033                form_validated = True
     1034            else:
     1035                form_validated = False
     1036                new_object = self.model()
     1037            prefixes = {}
     1038            for FormSet, inline in zip(self.get_formsets(request), inline_instances):
     1039                prefix = FormSet.get_default_prefix()
     1040                prefixes[prefix] = prefixes.get(prefix, 0) + 1
     1041                if prefixes[prefix] != 1 or not prefix:
     1042                    prefix = "%s-%s" % (prefix, prefixes[prefix])
     1043                formset = FormSet(data=request.POST, files=request.FILES,
     1044                                  instance=new_object,
     1045                                  prefix=prefix, queryset=inline.queryset(request))
     1046                formsets.append(formset)
     1047            if all_valid(formsets) and form_validated:
     1048                self.save_model(request, new_object, form, False)
     1049                self.save_related(request, form, formsets, False)
     1050                self.log_addition(request, new_object)
     1051                return self.response_add(request, new_object)
     1052        else:
     1053            initial = model_to_dict(original_obj)
     1054            form = ModelForm(initial=initial)
     1055            prefixes = {}
     1056            for FormSet, inline in zip(self.get_formsets(request, original_obj), inline_instances):
     1057                prefix = FormSet.get_default_prefix()
     1058                prefixes[prefix] = prefixes.get(prefix, 0) + 1
     1059                if prefixes[prefix] != 1 or not prefix:
     1060                    prefix = "%s-%s" % (prefix, prefixes[prefix])
     1061                formset = FormSet(instance=original_obj,
     1062                                  prefix=prefix,
     1063                                  save_as_new=True,
     1064                                  queryset=inline.queryset(request))
     1065                formsets.append(formset)
     1066
     1067        admin_form = helpers.AdminForm(form, list(self.get_fieldsets(request)),
     1068            self.get_prepopulated_fields(request),
     1069            self.get_readonly_fields(request),
     1070            model_admin=self)
     1071        media = self.media + admin_form.media
     1072
     1073        inline_admin_formsets = []
     1074        for inline, formset in zip(inline_instances, formsets):
     1075            fieldsets = list(inline.get_fieldsets(request, original_obj))
     1076            readonly = list(inline.get_readonly_fields(request, original_obj))
     1077            prepopulated = dict(inline.get_prepopulated_fields(request, original_obj))
     1078            inline_admin_formset = helpers.InlineAdminFormSet(inline, formset,
     1079                fieldsets, prepopulated, readonly, model_admin=self)
     1080            inline_admin_formsets.append(inline_admin_formset)
     1081            media = media + inline_admin_formset.media
     1082
     1083        context = {
     1084            'title': _('Add %s') % force_unicode(opts.verbose_name),
     1085            'adminform': admin_form,
     1086            'is_popup': "_popup" in request.REQUEST,
     1087            'show_delete': False,
     1088            'media': media,
     1089            'inline_admin_formsets': inline_admin_formsets,
     1090            'errors': helpers.AdminErrorList(form, formsets),
     1091            'app_label': opts.app_label,
     1092        }
     1093        context.update(extra_context or {})
     1094        return self.render_change_form(request, context, form_url=form_url, add=True)
     1095
    10121096    @csrf_protect_m
    10131097    @transaction.commit_on_success
    10141098    def change_view(self, request, object_id, form_url='', extra_context=None):
  • django/contrib/admin/templates/admin/submit_line.html

    diff --git a/django/contrib/admin/templates/admin/submit_line.html b/django/contrib/admin/templates/admin/submit_line.html
    index d6f854a..78bc255 100644
    a b  
    22<div class="submit-row">
    33{% if show_save %}<input type="submit" value="{% trans 'Save' %}" class="default" name="_save" {{ onclick_attrib }}/>{% endif %}
    44{% if show_delete_link %}<p class="deletelink-box"><a href="delete/" class="deletelink">{% trans "Delete" %}</a></p>{% endif %}
    5 {% if show_save_as_new %}<input type="submit" value="{% trans 'Save as new' %}" name="_saveasnew" {{ onclick_attrib }}/>{%endif%}
     5{% if show_save_as_new %}<p><a href="clone/">"{% trans 'Save as new' %}"</a></p>{%endif%}
    66{% if show_save_and_add_another %}<input type="submit" value="{% trans 'Save and add another' %}" name="_addanother" {{ onclick_attrib }} />{% endif %}
    77{% if show_save_and_continue %}<input type="submit" value="{% trans 'Save and continue editing' %}" name="_continue" {{ onclick_attrib }}/>{% endif %}
    88</div>
  • django/forms/models.py

    diff --git a/django/forms/models.py b/django/forms/models.py
    index cd8f027..6961eed 100644
    a b class BaseInlineFormSet(BaseModelFormSet):  
    682682    """A formset for child objects related to a parent."""
    683683    def __init__(self, data=None, files=None, instance=None,
    684684                 save_as_new=False, prefix=None, queryset=None, **kwargs):
     685
    685686        from django.db.models.fields.related import RelatedObject
    686687        if instance is None:
    687688            self.instance = self.fk.rel.to()
    class BaseInlineFormSet(BaseModelFormSet):  
    693694        if queryset is None:
    694695            queryset = self.model._default_manager
    695696        qs = queryset.filter(**{self.fk.name: self.instance})
     697
     698        initial = []
     699        if save_as_new:
     700            for obj in qs:
     701                initial.append(model_to_dict(obj, exclude=[self.fk.name,
     702                                                           self.instance._meta.pk.name]))
     703            # make sure original instance won't be reused
     704            self.instance = self.fk.rel.to()
     705
    696706        super(BaseInlineFormSet, self).__init__(data, files, prefix=prefix,
    697                                                 queryset=qs, **kwargs)
     707                                                queryset=qs, initial=initial, **kwargs)
    698708
    699709    def initial_form_count(self):
    700710        if self.save_as_new:
    701711            return 0
    702712        return super(BaseInlineFormSet, self).initial_form_count()
    703713
    704 
    705714    def _construct_form(self, i, **kwargs):
    706715        form = super(BaseInlineFormSet, self)._construct_form(i, **kwargs)
    707         if self.save_as_new:
    708             # Remove the primary key from the form's data, we are only
    709             # creating new instances
    710             form.data[form.add_prefix(self._pk_field.name)] = None
    711 
    712             # Remove the foreign key from the form's data
    713             form.data[form.add_prefix(self.fk.name)] = None
    714 
    715716        # Set the fk value here so that the form can do it's validation.
    716717        setattr(form.instance, self.fk.get_attname(), self.instance.pk)
    717718        return form
Back to Top