Beispiel #1
0
    def wrap_nested_inline_formsets(self, request, inline, formset):
        """wraps each formset in a helpers.InlineAdminFormset.
        @TODO someone with more inside knowledge should write done why this is done
        """
        media = None
        def get_media(extra_media):
            if media:
                return media + extra_media
            else:
                return extra_media

        for form in formset.forms:
            wrapped_nested_formsets = []
            for nested_inline, nested_formset in zip(inline.get_inline_instances(request), form.nested_formsets):
                if form.instance.pk:
                    instance = form.instance
                else:
                    instance = None
                fieldsets = list(nested_inline.get_fieldsets(request))
                readonly = list(nested_inline.get_readonly_fields(request))
                prepopulated = dict(nested_inline.get_prepopulated_fields(request))
                wrapped_nested_formset = InlineAdminFormSet(nested_inline, nested_formset,
                    fieldsets, prepopulated, readonly, model_admin=self)
                wrapped_nested_formsets.append(wrapped_nested_formset)
                media = get_media(wrapped_nested_formset.media)
                if nested_inline.inlines:
                    media = get_media(self.wrap_nested_inline_formsets(request, nested_inline, nested_formset))
            form.nested_formsets = wrapped_nested_formsets
        return media
    def _get_contentitem_formset_html(self, request, obj, FormSet, inline,
                                      placeholder_slots):
        # Passing serialized object fields to the client doesn't work,
        # as some form fields (e.g. picture field or MultiValueField) have a different representation.
        # The only way to pass a form copy to the client is by actually rendering it.
        # Hence, emulating change_view code here:
        formset = FormSet(instance=obj,
                          prefix='',
                          queryset=inline.queryset(request))
        fieldsets = list(inline.get_fieldsets(request, obj))
        readonly = list(inline.get_readonly_fields(request, obj))
        prepopulated = dict(inline.get_prepopulated_fields(request, obj))
        inline.extra = 0
        inline_admin_formset = InlineAdminFormSet(inline,
                                                  formset,
                                                  fieldsets,
                                                  prepopulated,
                                                  readonly,
                                                  model_admin=self)

        form_data = []
        for i, inline_admin_form in enumerate(inline_admin_formset):
            if inline_admin_form.original is None:  # The extra forms
                continue

            # exactly what admin/fluent_contents/contentitem/inline_container.html does:
            template_name = inline_admin_formset.opts.cp_admin_form_template
            form_html = render_to_string(
                template_name, {
                    'inline_admin_form': inline_admin_form,
                    'inline_admin_formset': inline_admin_formset,
                    'original': obj,
                    'object_id': obj.pk,
                    'add': False,
                    'change': True,
                    'has_change_permission': True,
                },
                context_instance=RequestContext(request))

            # Append to list with metadata included
            contentitem = inline_admin_form.original
            form_data.append({
                'contentitem_id':
                contentitem.pk,
                'sort_order':
                contentitem.sort_order,
                'placeholder_id':
                contentitem.placeholder_id,
                'placeholder_slot':
                placeholder_slots[contentitem.placeholder_id],
                'html':
                form_html,
                'plugin':
                inline.plugin.__class__.__name__,
                'model':
                inline.model.__name__,
                'prefix':
                formset.add_prefix(i),
            })
        return form_data
Beispiel #3
0
    def _get_contentitem_formset_html(self, request, obj, FormSet, inline,
                                      placeholder_slots):
        # Passing serialized object fields to the client doesn't work,
        # as some form fields (e.g. picture field or MultiValueField) have a different representation.
        # The only way to pass a form copy to the client is by actually rendering it.
        # Hence, emulating change_view code here:
        queryset = inline.get_queryset(request)
        formset = FormSet(instance=obj, prefix="", queryset=queryset)
        fieldsets = list(inline.get_fieldsets(request, obj))
        readonly = list(inline.get_readonly_fields(request, obj))
        prepopulated = dict(inline.get_prepopulated_fields(request, obj))
        inline.extra = 0
        inline_admin_formset = InlineAdminFormSet(inline,
                                                  formset,
                                                  fieldsets,
                                                  prepopulated,
                                                  readonly,
                                                  model_admin=self)

        form_data = []
        for i, inline_admin_form in enumerate(inline_admin_formset):
            if inline_admin_form.original is None:  # The extra forms
                continue

            # exactly what admin/fluent_contents/contentitem/inline_container.html does:
            template_name = inline_admin_formset.opts.cp_admin_form_template
            context = {
                "inline_admin_form": inline_admin_form,
                "inline_admin_formset": inline_admin_formset,
                "original": obj,
                "object_id": obj.pk,
                "add": False,
                "change": True,
                "has_change_permission": True,
            }
            context = RequestContext(request, context)
            form_html = render_to_string(template_name, context.flatten())

            # Append to list with metadata included
            contentitem = inline_admin_form.original
            form_data.append({
                "contentitem_id":
                contentitem.pk,
                "sort_order":
                contentitem.sort_order,
                "placeholder_id":
                contentitem.placeholder_id,
                "placeholder_slot":
                placeholder_slots[contentitem.placeholder_id],
                "html":
                form_html,
                "plugin":
                inline.plugin.__class__.__name__,
                "model":
                inline.model.__name__,
                "prefix":
                formset.add_prefix(i),
            })
        return form_data
 def add_nested_inline_formsets(self, request, inline, formset, depth=0):
     if depth > 5:
         raise Exception("Maximum nesting depth reached (5)")
     empty_form = formset.empty_form
     for form in formset.forms + [empty_form]:
         nested_formsets = []
         for nested_inline in inline.get_inline_instances(request):
             InlineFormSet = nested_inline.get_formset(request, form.instance)
             prefix = "%s-%s" % (form.prefix, InlineFormSet.get_default_prefix())
             #because of form nesting with extra=0 it might happen, that the post data doesn't include values for the formset.
             #This would lead to a Exception, because the ManagementForm construction fails. So we check if there is data available, and otherwise create an empty form
             keys = request.POST.keys()
             has_params = any(s.startswith(prefix) for s in keys)
             if request.method == 'POST' and has_params:
                 nested_formset = InlineFormSet(
                                 request.POST,
                                 request.FILES,
                                 save_as_new="_saveasnew" in request.POST,
                                 instance=form.instance,
                                 prefix=prefix,
                                 queryset=nested_inline.queryset(request)
                             )
             else:
                 nested_formset = InlineFormSet(instance=form.instance,
                                                prefix=prefix, queryset=nested_inline.queryset(request))
             nested_formsets.append(nested_formset)
             if nested_inline.inlines:
                 self.add_nested_inline_formsets(request, nested_inline, nested_formset, depth=depth+1)
         form.nested_formsets = nested_formsets
     form = empty_form
     media = None
     def get_media(extra_media):
         if media:
             return media + extra_media
         else:
             return extra_media
     wrapped_nested_formsets = []
     for nested_inline, nested_formset in zip(inline.get_inline_instances(request), form.nested_formsets):
          if form.instance.pk:
                 instance = form.instance
          else:
             instance = None
          fieldsets = list(nested_inline.get_fieldsets(request))
          readonly = list(nested_inline.get_readonly_fields(request))
          prepopulated = dict(nested_inline.get_prepopulated_fields(request))
          wrapped_nested_formset = InlineAdminFormSet(nested_inline, nested_formset,
              fieldsets, prepopulated, readonly, model_admin=self)
          wrapped_nested_formsets.append(wrapped_nested_formset)
          media = get_media(wrapped_nested_formset.media)
          if nested_inline.inlines:
              media = get_media(self.wrap_nested_inline_formsets(request, nested_inline, nested_formset))
     form.nested_formsets = wrapped_nested_formsets
     formset.__class__.empty_form = empty_form
    def change_view(self, request, object_id, form_url='', extra_context=None):
        "The 'change' admin view for this model."
        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=reverse('admin:%s_%s_add' %
                                 (opts.app_label, opts.module_name),
                                 current_app=self.admin_site.name))

        ModelForm = self.get_form(request, obj)
        formsets = []
        inline_instances = self.get_inline_instances(request, obj)
        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 self._get_formsets(request, new_object):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1 or not prefix:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(request.POST,
                                  request.FILES,
                                  instance=new_object,
                                  prefix=prefix,
                                  queryset=inline.get_queryset(request))
                formsets.append(formset)
                if inline.inlines:
                    self.add_nested_inline_formsets(request, inline, formset)

            if self.all_valid_with_nesting(formsets) and form_validated:
                self.save_model(request, new_object, form, True)
                self.save_related(request, form, formsets, 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 self._get_formsets(request, obj):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1 or not prefix:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(instance=obj,
                                  prefix=prefix,
                                  queryset=inline.get_queryset(request))
                formsets.append(formset)
                if inline.inlines:
                    self.add_nested_inline_formsets(request, inline, formset)

        adminForm = AdminForm(form,
                              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_admin_formsets = []
        for inline, formset in zip(inline_instances, formsets):
            fieldsets = list(inline.get_fieldsets(request, obj))
            readonly = list(inline.get_readonly_fields(request, obj))
            prepopulated = dict(inline.get_prepopulated_fields(request, obj))
            inline_admin_formset = InlineAdminFormSet(inline,
                                                      formset,
                                                      fieldsets,
                                                      prepopulated,
                                                      readonly,
                                                      model_admin=self)
            inline_admin_formsets.append(inline_admin_formset)
            media = media + inline_admin_formset.media
            if inline.inlines:
                media = media + self.wrap_nested_inline_formsets(
                    request, inline, formset)

        context = {
            'title': _('Change %s') % force_unicode(opts.verbose_name),
            'adminform': adminForm,
            'object_id': object_id,
            'original': obj,
            'is_popup': "_popup" in request.POST,
            'media': media,
            'inline_admin_formsets': inline_admin_formsets,
            'errors': AdminErrorList(form, formsets),
            'app_label': opts.app_label,
            'django_version_lt_1_6': DJANGO_VERSION < (1, 6)
        }
        context.update(extra_context or {})
        return self.render_change_form(request,
                                       context,
                                       change=True,
                                       obj=obj,
                                       form_url=form_url)
    def add_view(self, request, form_url='', extra_context=None):
        "The 'add' admin view for this model."
        model = self.model
        opts = model._meta

        if not self.has_add_permission(request):
            raise PermissionDenied

        ModelForm = self.get_form(request)
        formsets = []
        inline_instances = self.get_inline_instances(request, None)
        if request.method == 'POST':
            form = ModelForm(request.POST, request.FILES)
            if form.is_valid():
                new_object = self.save_form(request, form, change=False)
                form_validated = True
            else:
                form_validated = False
                new_object = self.model()
            prefixes = {}
            for FormSet, inline in self._get_formsets(request):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1 or not prefix:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(data=request.POST,
                                  files=request.FILES,
                                  instance=new_object,
                                  save_as_new="_saveasnew" in request.POST,
                                  prefix=prefix,
                                  queryset=inline.get_queryset(request))
                formsets.append(formset)
                if inline.inlines:
                    self.add_nested_inline_formsets(request, inline, formset)
            if self.all_valid_with_nesting(formsets) and form_validated:
                self.save_model(request, new_object, form, False)
                self.save_related(request, form, formsets, False)

                if DJANGO_VERSION < (1, 9):
                    change_message = self.construct_change_message(
                        request, form, formsets)
                    self.log_addition(request, new_object)
                else:
                    change_message = self.construct_change_message(
                        request, form, formsets, True)
                    self.log_addition(request, new_object, change_message)

                return self.response_add(request, new_object)
        else:
            # Prepare the dict of initial data from the request.
            # We have to special-case M2Ms as a list of comma-separated PKs.
            initial = dict(request.GET.items())
            for k in initial:
                try:
                    f = opts.get_field(k)
                except models.FieldDoesNotExist:
                    continue
                if isinstance(f, models.ManyToManyField):
                    initial[k] = initial[k].split(",")
            form = ModelForm(initial=initial)
            prefixes = {}
            for FormSet, inline in self._get_formsets(request):
                prefix = FormSet.get_default_prefix()
                prefixes[prefix] = prefixes.get(prefix, 0) + 1
                if prefixes[prefix] != 1 or not prefix:
                    prefix = "%s-%s" % (prefix, prefixes[prefix])
                formset = FormSet(instance=self.model(),
                                  prefix=prefix,
                                  queryset=inline.get_queryset(request))
                formsets.append(formset)
                if inline.inlines:
                    self.add_nested_inline_formsets(request, inline, formset)

        adminForm = AdminForm(form,
                              list(self.get_fieldsets(request)),
                              self.get_prepopulated_fields(request),
                              self.get_readonly_fields(request),
                              model_admin=self)
        media = self.media + adminForm.media

        inline_admin_formsets = []
        for inline, formset in zip(inline_instances, formsets):
            fieldsets = list(inline.get_fieldsets(request))
            readonly = list(inline.get_readonly_fields(request))
            prepopulated = dict(inline.get_prepopulated_fields(request))
            inline_admin_formset = InlineAdminFormSet(inline,
                                                      formset,
                                                      fieldsets,
                                                      prepopulated,
                                                      readonly,
                                                      model_admin=self)
            inline_admin_formsets.append(inline_admin_formset)
            media = media + inline_admin_formset.media
            if inline.inlines:
                media = media + self.wrap_nested_inline_formsets(
                    request, inline, formset)

        context = {
            'title': _('Add %s') % force_unicode(opts.verbose_name),
            'adminform': adminForm,
            'is_popup': "_popup" in request.POST,
            'show_delete': False,
            'media': media,
            'inline_admin_formsets': inline_admin_formsets,
            'errors': AdminErrorList(form, formsets),
            'app_label': opts.app_label,
            'django_version_lt_1_6': DJANGO_VERSION < (1, 6)
        }
        context.update(extra_context or {})
        return self.render_change_form(request,
                                       context,
                                       form_url=form_url,
                                       add=True)