def all_valid_with_nesting(formsets): """ Checks validation on formsets, then handles a case where an inline has new data but one of its parent forms is blank. This causes a bug when one of the parent forms has empty_permitted == True, which happens if it is an "extra" form in the formset and its index is >= the formset's min_num. """ if not all_valid(formsets): return False for formset in formsets: if formset.has_changed() and getattr(formset, 'parent_form', None): parent_form = formset.parent_form while True: if parent_form.empty_permitted: parent_form.empty_permitted = False # Reset the validation errors parent_form._errors = None if not hasattr(parent_form, 'parent_formset'): break parent_form.parent_formset._errors = None if not hasattr(parent_form.parent_formset, 'parent_form'): break parent_form = parent_form.parent_formset.parent_form if not all_valid(formsets): return False return True
def post(self, request, *args, **kwargs): """ Handles POST requests, instantiating a form and formset instances with the passed POST variables and then checked for validity. """ self.object = None form_class = self.get_form_class() form = self.get_form(form_class) if form.is_valid(): self.object = form.save(commit=False) # TODO - Clean this # TODO - Read the Django documentation # TODO - Convert this nonsense to the *actual* mixin hooks # FFS self.object.private = True self.object.n1trial = True self.object.reporting_style = self.object.WHENEVER self.object.instruction_delivery = self.object.ON_DEMAND form_validated = True else: form_validated = False inlines = self.construct_inlines() if all_valid(inlines) and form_validated: response = self.forms_valid(form, inlines) self.object.join(self.request.user) return response return self.forms_invalid(form, inlines)
def post(self, request, *args, **kwargs): # Create or Update try: self.object = self.get_object() self.new_object = False except AttributeError: self.object = self.model() self.new_object = True # ProcessFormView form_class = self.get_form_class() form = self.get_form(form_class) if form.is_valid(): self.object = form.save(commit=False) # ProcessFormSetsViewV self.construct_formsets() if all_valid(self.formsets_instances): return self.form_valid(form) else: # ProcessFormSetsViewV self.construct_formsets() return self.form_invalid(form)
def process_form(self, request, instance=None, change=None): """ form processor used by add_view and edit_view """ new_instance = None valid = False ModelForm = self.get_form(request, instance, change=change) if request.method == 'POST': form = self.get_form_instance(request, ModelForm, instance=instance, change=change) if form.is_valid(): new_instance = self.save_form(request, form, change=change) form_validated = True else: new_instance = instance if (instance is not None) else self.model() form_validated = False formsets = self.get_formset_instances(request, instance=new_instance, change=change) if all_valid(formsets.itervalues()) and form_validated: with transaction.commit_on_success(): self.save_model(request, new_instance, form, change=change) form.save_m2m() self.save_formsets(request, form, formsets, change=change) self.post_save(request, new_instance, form, formsets, change=change) valid = True else: form = self.get_form_instance(request, ModelForm, instance=instance, change=change,) formsets = self.get_formset_instances(request, instance=instance, change=change) return form, formsets, new_instance, valid
def post(self, request, *args, **kwargs): self.object = None form_class = self.get_form_class() form = self.get_form(form_class) ticket_forms = self.construct_ticket_forms(data=request.POST) if form.is_valid(): self.object = form.save(commit=False) form_validated = True else: form_validated = False inlines = self.construct_inlines() if all_valid(inlines) and all_valid(ticket_forms) and form_validated: return self.forms_valid(form, inlines, ticket_forms) return self.forms_invalid(form, inlines, ticket_forms)
def post(self, request, *args, **kwargs): forms = {} for key in self.get_form_class_dict().keys(): forms[key] = self.get_form(key) if all_valid(forms.values()): return self.form_valid(forms) else: return self.form_invalid(forms)
def add_view(self, request, form_url='', extra_context=None): "The 'add' admin view for this model." model = self.model opts = model._meta app_label = opts.app_label if not self.has_add_permission(request): raise PermissionDenied if self.has_change_permission(request, None): # redirect to list view post_url = '../' else: # Object list will give 'Permission Denied', so go back to admin home post_url = '../../../' ModelForm = self.get_form(request) inline_formsets = [] obj = self.model() if request.method == 'POST': form = ModelForm(request.POST, request.FILES) for FormSet in self.get_formsets(request): inline_formset = FormSet(data=request.POST, files=request.FILES, instance=obj, save_as_new="_saveasnew" in request.POST) inline_formsets.append(inline_formset) if all_valid(inline_formsets) and form.is_valid(): return self.save_add(request, form, inline_formsets, '../%s/') else: form = ModelForm(initial=dict(list(request.GET.items()))) for FormSet in self.get_formsets(request): inline_formset = FormSet(instance=obj) inline_formsets.append(inline_formset) adminForm = AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields) media = self.media + adminForm.media for fs in inline_formsets: media = media + fs.media inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, inline_formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = InlineAdminFormSet(inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) context = { 'title': _('Add %s') % opts.verbose_name, 'adminform': adminForm, 'is_popup': '_popup' in request.REQUEST, 'show_delete': False, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': AdminErrorList(form, inline_formsets), 'root_path': self.admin_site.root_path, } context.update(extra_context or {}) return self.render_change_form(request, context, add=True)
def register_view(self, request, form_url='', extra_context=None): request.user = STAFF_REGISTER ModelForm = self.get_form(request, None) if request.method == 'POST': form = ModelForm(request.POST, request.FILES, instance=None) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=False) else: form_validated = False new_object = form.instance formsets, inline_instances = self._create_formsets(request, new_object) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, False) self.log_addition(request, new_object) return self.response_add(request, new_object, post_url_continue='/management/login/') else: initial = self.get_changeform_initial_data(request) form = ModelForm(initial=initial) formsets, inline_instances = self._create_formsets(request, self.model()) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request, None)), self.get_prepopulated_fields(request, None), self.get_readonly_fields(request, None), model_admin=self) media = self.media + adminForm.media inline_formsets = self.get_inline_formsets(request, formsets, inline_instances, None) for inline_formset in inline_formsets: media = media + inline_formset.media context = dict(self.admin_site.each_context(), title=u'注册%s' % force_text(self.model._meta.verbose_name), adminform=adminForm, object_id=None, original=None, is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=None, media=media, # formsets=formsets, inline_admin_formsets=inline_formsets, errors=helpers.AdminErrorList(form, formsets), preserved_filters=self.get_preserved_filters(request)) context.update(extra_context or {}) return self.render_change_form(request, context, add=True, change=False, obj=None, form_url=form_url)
def get_change_view_object(self, request, object_id=None): model = self.model opts = model._meta obj = self.get_object(request, unquote(object_id)) inline_objects = new_object = None 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)}) #FIXME is it possible to use _saveasnew? 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) form = ModelForm(request.POST, request.FILES, instance=obj) if form.is_valid(): new_object = prepeare_object( self.save_form(request, form, change=False), get_random_string(GET_SETTING('XANAX_PREVIEW_TOKEN_LENGTH')) ) cleaned_data = form.cleaned_data for f in new_object._meta.many_to_many: if f.name in cleaned_data: prepare_M2M_field( new_object, f.name, m2m_related_list=cleaned_data[f.name] ) else: return None, None prefixes = {} for FormSet, inline in zip(self.get_formsets(request, new_object), inline_instances): 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.queryset(request)) formsets.append(formset) if all_valid(formsets): inline_objects = get_inline_objects(formsets) else: return None, None new_object = prepare_M2M_set(new_object, inline_objects) return new_object, inline_objects
def post(self, request, *args, **kwargs): form_class = self.get_form_class() form = self.get_form(form_class) if form.is_valid(): self.object = form.save(commit=False) inlines = self.construct_inlines() if all_valid(inlines): return self.forms_valid(form, inlines) else: return self.forms_invalid(form, inlines) return self.forms_invalid(form, self.construct_inlines())
def change_view(self, request, object_id, extra_context=None): obj = self.get_object(request, unquote(object_id)) if obj.preflight: return HttpResponseRedirect('push/') if '_save_and_push' not in request.POST: return super(BatchAdmin, self).change_view( request, object_id, extra_context=extra_context) else: ModelForm = self.get_form(request, obj) formsets = [] 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 = {} if hasattr(self, 'inline_instances'): inline_instances = self.inline_instances else: inline_instances = [] zipped_formsets = zip(self.get_formsets(request, new_object), inline_instances) for FormSet, inline in zipped_formsets: prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix, queryset=inline.queryset(request)) formsets.append(formset) 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 HttpResponseRedirect('push/') context = {}.update(extra_context) return self.render_change_form(request, context, change=True, obj=obj)
def is_valid(self): valid = True for form in self.forms: form = form[1] if isinstance(form,BaseForm): if not form.is_valid(): all = form._errors.get('__all__') if all: if not self._errors: self._errors = all else: self._errors.extend(all) valid = False return valid and all_valid(self.formsets)
def post(self, request, *args, **kwargs): """ Handles POST requests. Gets formsets and validates them. If all are valid then it passes the formsets list to the all_valid() method for processing/saving. If validation fails, the page is re-rendered with the formset instances that failed validation. """ formsets = self.get_formsets() if all_valid(formsets): return self.all_valid(formsets) else: context = {"formsets": formsets} return self.render_to_response(self.get_context_data(**context))
def all_valid(self, formsets): if not all_valid(formsets): return False for formset in formsets: if formset.is_bound: for form in formset: if hasattr(form, 'recursive_formsets') and form.recursive_formsets: if not self.all_valid(form.recursive_formsets): return False # gross gross gross if not form.cleaned_data: form._errors['__all__'] = form.error_class(["Parent object must be created when creating nested inlines."]) return False return True
def preview(self, request): """ Preview an article """ # model = self.model TODO: Understand why these lines are here # 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) if request.method == 'POST': form = ModelForm(request.POST, request.FILES) if not form.is_valid(): raise Http404("Invalid Article to Preview. Article Form.") article = { 'image_inines': form.cleaned_data['image_inlines'], 'video_inlines': form.cleaned_data['video_inlines'], 'audio_inlines': form.cleaned_data['audio_inlines'], 'document_inlines': form.cleaned_data['document_inlines'], 'object_inlines': form.cleaned_data['object_inlines'], 'external_inlines': form.cleaned_data['external_inlines'], } prefixes = {} for FormSet, inline in zip(self.get_formsets(request), inline_instances): 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=self.model(), save_as_new=True, prefix=prefix, queryset=inline.queryset(request)) formsets.append(formset) if all_valid(formsets): translations = formsets[0].cleaned_data return TemplateResponse(request, "admin/newsengine/article/preview.html", {'article': article, 'translations': translations}, current_app=self.admin_site.name) else: raise Http404("Invalid Article to Preview. Translation Form") else: raise PermissionDenied
def change_view(self, request, object_id, form_url='', extra_context=None): context = {} context.update(extra_context or {}) if not self.form_change_actions is None: obj = self.get_object(request, object_id) if isinstance(self.form_change_actions, basestring) and self.form_change_actions in dir(obj): getFormActions = getattr(obj, self.form_change_actions) if callable(getFormActions): context['form_actions'] = getFormActions() else: context['form_actions'] = self.form_change_actions if self.DELETE_FORM_ACTION in context['form_actions']: context['form_actions'].remove(self.DELETE_FORM_ACTION) context['has_delete_permission'] = True else: context['has_delete_permission'] = False for actionConfig in context['form_actions']: if request.method == 'POST' and actionConfig.has_key('name') and actionConfig['name'] in request.POST \ and (actionConfig.has_key('modelAction') or actionConfig.has_key('action')): ModelForm = self.get_form(request, obj) 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 = form.instance formsets, inline_instances = self._create_formsets(request, new_object) if all_valid(formsets) and form_validated: if actionConfig.has_key('modelAction') and actionConfig['modelAction'] in dir(new_object): save_action = getattr(new_object, actionConfig['modelAction']) if callable(save_action): save_action() 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) if actionConfig.has_key('action') and actionConfig['action'] in dir(self): adminAction = getattr(self, actionConfig['action']) if callable(adminAction): ret = adminAction(request, [new_object]) if isinstance(ret, HttpResponse): return ret return self.response_change(request, new_object) return super(CustomChangeActionsModelAdmin, self).change_view(request, object_id, form_url, context)
def all_valid_with_nesting(self, formsets): "Recursively validate all nested formsets" if not all_valid(formsets): return False for formset in formsets: if not formset.is_bound: pass for form in formset: if hasattr(form, 'nested_formsets'): if not self.all_valid_with_nesting(form.nested_formsets): return False #TODO - find out why this breaks when extra = 1 and just adding new item with no sub items if (not hasattr(form, 'cleaned_data') or not form.cleaned_data) and self.formset_has_nested_data(form.nested_formsets): form._errors["__all__"] = form.error_class([u"Parent object must be created when creating nested inlines."]) return False return True
def post_submit(self, request, person_id, extra_form_args={}, template_name='person_edit.html', extra_context={}): context = self.get_context(person_id=person_id, extra_form_args=extra_form_args, extra_context=extra_context) person_form = context['person_form'] contact_info_form = context['contact_info_form'] if person_form.is_valid(): person_form.save() if contact_info_form.is_valid(): contact_info_form.save() if all_valid([contact_info_form, person_form]): return HttpResponseRedirect(reverse('index')) return render(request, template_name, context)
def post(self, request, *args, **kwargs): """ Handles POST requests, instantiating a form and formset instances with the passed POST variables and then checked for validity. """ form_class = self.get_form_class() form = self.get_form(form_class) if form.is_valid(): self.object = form.save(commit=False) form_validated = True else: form_validated = False inlines = self.construct_inlines() if all_valid(inlines) and form_validated: return self.forms_valid(form, inlines) return self.forms_invalid(form, inlines)
def get_change_view_formsets(self, request, obj): formsets = [] ModelForm = self.get_form(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 in self.get_formsets(request, new_object): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix) formsets.append(formset) 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), None else: form = ModelForm(instance=obj) prefixes = {} for FormSet in self.get_formsets(request, obj): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) return formsets, form
def post(self, request, *args, **kwargs): self.object = None if django.VERSION >= (1, 6) and self.fields is None and self.form_class is None: self.fields = '__all__' # backward compatible with older versions form_class = self.get_form_class() form = self.get_form(form_class) if form.is_valid(): self.object = form.save(commit=False) self.object.creator = self.request.user form_validated = True else: form_validated = False inlines = self.construct_inlines() if all_valid(inlines) and form_validated: return self.forms_valid(form, inlines) return self.forms_invalid(form, inlines)
def post(self, request, *args, **kwargs): """ Handles POST requests, instantiating a form and formset instances with the passed POST variables and then checked for validity. """ if django.VERSION >= (1, 6) and self.fields is None and self.form_class is None: self.fields = '__all__' # backward compatible with older versions form_class = self.get_form_class() form = self.get_form(form_class) if form.is_valid(): self.object = form.save(commit=False) form_validated = True else: form_validated = False inlines = self.construct_inlines() if all_valid(inlines) and form_validated: return self.forms_valid(form, inlines) return self.forms_invalid(form, inlines)
def process_form(self, request, instance=None, change=None): """ Processes forms, used by ``add_view`` and ``edit_view`` """ new_instance = None valid = False ModelForm = self.get_form(request, instance, change=change) if request.method == 'POST': form = self.get_form_instance( request, ModelForm, instance=instance, change=change) if form.is_valid(): new_instance = self.save_form(request, form, change=change) form_validated = True else: new_instance = self.model() if instance is None else instance form_validated = False formsets = self.get_formset_instances( request, instance=new_instance, change=change) if all_valid(formsets.values()) and form_validated: with transaction.atomic(): self.save_model(request, new_instance, form, change=change) form.save_m2m() self.save_formsets(request, form, formsets, change=change) self.post_save( request, new_instance, form, formsets, change=change) valid = True else: form = self.get_form_instance( request, ModelForm, instance=instance, change=change) formsets = self.get_formset_instances( request, instance=instance, change=change) return form, formsets, new_instance, valid
def get_add_view_object(self, request): formsets = [] inline_objects = new_object = None ModelForm = self.get_form(request) form = ModelForm(request.POST, request.FILES) inline_instances = self.get_inline_instances(request) if form.is_valid(): new_object = prepeare_object( self.save_form(request, form, change=False), get_random_string(GET_SETTING('XANAX_PREVIEW_TOKEN_LENGTH')) ) cleaned_data = form.cleaned_data for f in new_object._meta.many_to_many: if f.name in cleaned_data: prepare_M2M_field( new_object, f.name, m2m_related_list=cleaned_data[f.name] ) else: return None, None prefixes = {} for FormSet, inline in zip(self.get_formsets(request), inline_instances): 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.queryset(request)) formsets.append(formset) if all_valid(formsets): inline_objects = get_inline_objects(formsets) else: return None, None return new_object, inline_objects
def add_view(self, request, form_url='', extra_context=None): """ Like the original add_view from ModelAdmin. Alterations are marked with # ----start # ----end """ "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 = [] if request.method == 'POST': form = ModelForm(request.POST, request.FILES) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=False) else: form_validated = False new_object = self.model() prefixes = {} for FormSet in self.get_formsets(request): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(data=request.POST, files=request.FILES, instance=new_object, save_as_new=request.POST.has_key("_saveasnew"), prefix=prefix) formsets.append(formset) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, change=False) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=False) self.log_addition(request, new_object) 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 in self.get_formsets(request): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=self.model(), prefix=prefix) formsets.append(formset) # --start-- adminForm = Tabset(form, self.tabs, self.prepopulated_fields) # --original-- # adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields) # --end-- media = self.media + adminForm.media # --start-- (identical to the one in change_view, except for not passing obj in get_fieldsets) inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) tab = adminForm.get_tab_that_has_inline(inline.__class__.__name__) if not tab==None: tab.inlines.append(inline_admin_formset) else: inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media # --original-- ''' inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media ''' # --end-- context = { 'title': _('Add %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'is_popup': request.REQUEST.has_key('_popup'), 'show_delete': False, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, form_url=form_url, add=True)
def render_revision_form(self, request, obj, version, context, revert=False, recover=False): """Renders the object revision form.""" model = self.model opts = model._meta object_id = obj.pk # Generate the model form. ModelForm = self.get_form(request, obj) formsets = [] if request.method == "POST": # This section is copied directly from the model admin change view # method. Maybe one day there will be a hook for doing this better. form = ModelForm(request.POST, request.FILES, instance=obj, initial=self.get_revision_form_data( request, obj, version)) 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.inline_instances): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix, queryset=inline.queryset(request)) # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: # Strip extra empty forms from the formset. empty_forms = [] post_keys = request.POST.keys() for f in formset.forms: # the forms that can be removed, are not in the request.POST # we can find them by their prefix matches_prefix = lambda var: var.find(f.prefix ) == 0 or None if first_match(matches_prefix, post_keys) is None: empty_forms.append(f) else: # the form must be cleaned, which they aren't yet because # we just created them f.full_clean() # modify form settings of formset. num_forms = formset.total_form_count() - len(empty_forms) formset.forms = filter(lambda x: x not in empty_forms, formset.forms) formset.total_form_count = lambda: num_forms # end of non copy pasted piece # Add this hacked formset to the form. formsets.append(formset) 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) # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: self.update_draft(version, request) change_message = _(u"Publisher message %(datetime)s") % { "datetime": format(version.revision.date_created, _(settings.DATETIME_FORMAT)) } self.log_change(request, new_object, change_message) self.message_user( request, _(u'%(model)s "%(name)s" publisher message.') % { "model": force_unicode(opts.verbose_name), "name": unicode(obj) }) # end of not copy pasted code # Redirect to the model change form. if revert: return HttpResponseRedirect("../../") elif recover: return HttpResponseRedirect("../../%s/" % object_id) else: assert False else: # This is a mutated version of the code in the standard model admin # change_view. Once again, a hook for this kind of functionality # would be nice. Unfortunately, it results in doubling the number # of queries required to construct the formets. form = ModelForm(instance=obj, initial=self.get_revision_form_data( request, obj, version)) prefixes = {} revision_versions = version.revision.version_set.all() for FormSet, inline in zip(self.get_formsets(request, obj), self.inline_instances): # This code is standard for creating the formset. prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix, queryset=inline.queryset(request)) # Now we hack it to push in the data from the revision! try: fk_name = FormSet.fk.name except AttributeError: # This is a GenericInlineFormset, or similar. fk_name = FormSet.ct_fk_field.name # _ _ _ ____ ___ ____ _ _ ____ _ _ ___ # | | | |__| | | |__| | | | | | # |_|_| | | | |___ | | |__| |__| | # this is not copy pasted: related_versions = [ (related_version.object_id, related_version) for related_version in revision_versions if ContentType.objects.get_for_id( related_version.content_type_id).model_class() == FormSet.model and unicode(related_version.field_dict[fk_name]) == unicode(object_id) ] # all items that do not have their id filled in must stay. # if they do in fact have an id, we only want the last one, # no duplicates. related_versions = [(key, value) for (key, value) in related_versions if key == 'None'] + \ dict([(key, value) for (key, value) in related_versions if key != 'None']).items() initial = [] for related_obj in formset.queryset: related_versions_dict = dict(related_versions) if unicode(related_obj.pk) in related_versions_dict: initial.append( related_versions_dict.pop(unicode( related_obj.pk)).field_dict) else: initial_data = model_to_dict(related_obj) initial_data["DELETE"] = True initial.append(initial_data) for (key, related_version) in related_versions: initial_row = related_version.field_dict try: del initial_row["id"] except KeyError: # when multiple inlines with the same model but a different # querysets are on a page, it could happen that we allready # deleted the id. pass # we didn't convert related_versions to a dict so there can be # duplicate keys in the thingy if not initial_row in initial: initial.append(initial_row) # end of non copy pasted piece # Reconstruct the forms with the new revision data. formset.initial = initial formset.forms = [ formset._construct_form(n) for n in xrange(len(initial)) ] # Add this hacked formset to the form. formsets.append(formset) # Generate admin form helper. 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 # Generate formset helpers. inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, 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) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media # Generate the context. context.update({ "adminform": adminForm, "object_id": object_id, "original": obj, "is_popup": False, "media": mark_safe(media), "inline_admin_formsets": inline_admin_formsets, "errors": helpers.AdminErrorList(form, formsets), "app_label": opts.app_label, "add": False, "change": True, "has_add_permission": self.has_add_permission(request), "has_change_permission": self.has_change_permission(request, obj), "has_delete_permission": self.has_delete_permission(request, obj), "has_file_field": True, "has_absolute_url": getattr(self.model, 'get_absolute_url', False), "ordered_objects": opts.get_ordered_objects(), "form_url": mark_safe(request.path), "opts": opts, "content_type_id": ContentType.objects.get_for_model(self.model).id, "save_as": False, "save_on_top": self.save_on_top, "changelist_url": reverse("admin:%s_%s_changelist" % (opts.app_label, opts.module_name)), "change_url": reverse("admin:%s_%s_change" % (opts.app_label, opts.module_name), args=(obj.pk, )), "history_url": reverse("admin:%s_%s_history" % (opts.app_label, opts.module_name), args=(obj.pk, )), "recoverlist_url": reverse("admin:%s_%s_recoverlist" % (opts.app_label, opts.module_name)) }) # Render the form. if revert: form_template = self.revision_form_template elif recover: form_template = self.recover_form_template else: assert False return render_to_response(form_template, context, template.RequestContext(request))
def render_revision_form(self, request, obj, version, context, revert=False, recover=False): """Renders the object revision form.""" model = self.model opts = model._meta object_id = obj.pk # Generate the model form. ModelForm = self.get_form(request, obj) formsets = [] if request.method == "POST": # This section is copied directly from the model admin change view # method. Maybe one day there will be a hook for doing this better. form = ModelForm(request.POST, request.FILES, instance=obj, initial=self.get_revision_form_data( request, obj, version)) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) # HACK: If the value of a file field is None, remove the file from the model. for field in new_object._meta.fields: if isinstance( field, models.FileField ) and field.name in form.cleaned_data and form.cleaned_data[ field.name] is None: setattr(new_object, field.name, None) else: form_validated = False new_object = obj prefixes = {} for FormSet, inline in zip(self.get_formsets(request, new_object), self.inline_instances): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix, queryset=inline.queryset(request)) self._hack_inline_formset_initial(FormSet, formset, obj, version, revert, recover) # Add this hacked formset to the form. formsets.append(formset) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, change=True) form.save_m2m() for formset in formsets: # HACK: If the value of a file field is None, remove the file from the model. related_objects = formset.save(commit=False) for related_obj, related_form in zip( related_objects, formset.saved_forms): for field in related_obj._meta.fields: if isinstance( field, models.FileField ) and field.name in related_form.cleaned_data and related_form.cleaned_data[ field.name] is None: setattr(related_obj, field.name, None) related_obj.save() formset.save_m2m() change_message = _( u"Reverted to previous version, saved on %(datetime)s") % { "datetime": format(version.revision.date_created, _('DATETIME_FORMAT')) } self.log_change(request, new_object, change_message) self.message_user( request, _(u'The %(model)s "%(name)s" was reverted successfully. You may edit it again below.' ) % { "model": force_unicode(opts.verbose_name), "name": unicode(obj) }) # Redirect to the model change form. if revert: return HttpResponseRedirect("../../") elif recover: return HttpResponseRedirect("../../%s/" % object_id) else: assert False else: # This is a mutated version of the code in the standard model admin # change_view. Once again, a hook for this kind of functionality # would be nice. Unfortunately, it results in doubling the number # of queries required to construct the formets. form = ModelForm(instance=obj, initial=self.get_revision_form_data( request, obj, version)) prefixes = {} for FormSet, inline in zip(self.get_formsets(request, obj), self.inline_instances): # This code is standard for creating the formset. prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix, queryset=inline.queryset(request)) self._hack_inline_formset_initial(FormSet, formset, obj, version, revert, recover) # Add this hacked formset to the form. formsets.append(formset) # Generate admin form helper. 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 # Generate formset helpers. inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, 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) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media # Generate the context. context.update({ "adminform": adminForm, "object_id": object_id, "original": obj, "is_popup": False, "media": mark_safe(media), "inline_admin_formsets": inline_admin_formsets, "errors": helpers.AdminErrorList(form, formsets), "app_label": opts.app_label, "add": False, "change": True, "revert": revert, "recover": recover, "has_add_permission": self.has_add_permission(request), "has_change_permission": self.has_change_permission(request, obj), "has_delete_permission": self.has_delete_permission(request, obj), "has_file_field": True, "has_absolute_url": False, "ordered_objects": opts.get_ordered_objects(), "form_url": mark_safe(request.path), "opts": opts, "content_type_id": ContentType.objects.get_for_model(self.model).id, "save_as": False, "save_on_top": self.save_on_top, "changelist_url": reverse("%s:%s_%s_changelist" % (self.admin_site.name, opts.app_label, opts.module_name)), "change_url": reverse("%s:%s_%s_change" % (self.admin_site.name, opts.app_label, opts.module_name), args=(obj.pk, )), "history_url": reverse("%s:%s_%s_history" % (self.admin_site.name, opts.app_label, opts.module_name), args=(obj.pk, )), "recoverlist_url": reverse("%s:%s_%s_recoverlist" % (self.admin_site.name, opts.app_label, opts.module_name)) }) # Render the form. if revert: form_template = self.revision_form_template or self._get_template_list( "revision_form.html") elif recover: form_template = self.recover_form_template or self._get_template_list( "recover_form.html") else: assert False return render_to_response(form_template, context, template.RequestContext(request))
def edit_permissions(modeladmin, request, queryset): opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has the permission to edit permissions if not (request.user.is_superuser or request.user.has_perm('authority.change_permission') or request.user.has_perm('authority.change_foreign_permissions')): raise PermissionDenied inline = ActionPermissionInline(queryset.model, modeladmin.admin_site) formsets = [] for obj in queryset: prefixes = {} FormSet = inline.get_formset(request, obj) prefix = "%s-%s" % (FormSet.get_default_prefix(), obj.pk) prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s-%s" % (prefix, prefixes[prefix]) if request.POST.get('post'): formset = FormSet(data=request.POST, files=request.FILES, instance=obj, prefix=prefix) else: formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) media = modeladmin.media inline_admin_formsets = [] for formset in formsets: fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet( inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media ordered_objects = opts.get_ordered_objects() if request.POST.get('post'): if all_valid(formsets): for formset in formsets: formset.save() # redirect to full request path to make sure we keep filter return HttpResponseRedirect(request.get_full_path()) context = { 'errors': ActionErrorList(formsets), 'title': ugettext('Permissions for %s') % force_unicode(opts.verbose_name_plural), 'inline_admin_formsets': inline_admin_formsets, 'root_path': modeladmin.admin_site.root_path, 'app_label': app_label, 'change': True, 'ordered_objects': ordered_objects, 'form_url': mark_safe(''), 'opts': opts, 'target_opts': queryset.model._meta, 'content_type_id': ContentType.objects.get_for_model(queryset.model).id, 'save_as': False, 'save_on_top': False, 'is_popup': False, 'media': mark_safe(media), 'show_delete': False, 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, 'queryset': queryset, "object_name": force_unicode(opts.verbose_name), } template_name = getattr(modeladmin, 'permission_change_form_template', [ "admin/%s/%s/permission_change_form.html" % (app_label, opts.object_name.lower()), "admin/%s/permission_change_form.html" % app_label, "admin/permission_change_form.html" ]) return render_to_response( template_name, context, context_instance=template.RequestContext(request))
def edit_permissions(modeladmin, request, queryset): opts = modeladmin.model._meta app_label = opts.app_label # Check that the user has the permission to edit permissions if not ( request.user.is_superuser or request.user.has_perm("authority.change_permission") or request.user.has_perm("authority.change_foreign_permissions") ): raise PermissionDenied inline = ActionPermissionInline(queryset.model, modeladmin.admin_site) formsets = [] for obj in queryset: prefixes = {} FormSet = inline.get_formset(request, obj) prefix = "%s-%s" % (FormSet.get_default_prefix(), obj.pk) prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) if request.POST.get("post"): formset = FormSet( data=request.POST, files=request.FILES, instance=obj, prefix=prefix ) else: formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) media = modeladmin.media inline_admin_formsets = [] for formset in formsets: fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media if request.POST.get("post"): if all_valid(formsets): for formset in formsets: formset.save() else: modeladmin.message_user( request, "; ".join( err.as_text() for formset in formsets for err in formset.errors ), ) # redirect to full request path to make sure we keep filter return HttpResponseRedirect(request.get_full_path()) context = { "errors": ActionErrorList(formsets), "title": ugettext("Permissions for %s") % force_text(opts.verbose_name_plural), "inline_admin_formsets": inline_admin_formsets, "app_label": app_label, "change": True, "form_url": mark_safe(""), "opts": opts, "target_opts": queryset.model._meta, "content_type_id": ContentType.objects.get_for_model(queryset.model).id, "save_as": False, "save_on_top": False, "is_popup": False, "media": mark_safe(media), "show_delete": False, "action_checkbox_name": helpers.ACTION_CHECKBOX_NAME, "queryset": queryset, "object_name": force_text(opts.verbose_name), } template_name = getattr( modeladmin, "permission_change_form_template", [ "admin/%s/%s/permission_change_form.html" % (app_label, opts.object_name.lower()), "admin/%s/permission_change_form.html" % app_label, "admin/permission_change_form.html", ], ) return render_to_response(template_name, context, request)
def change_view(self, request, object_id, extra_context=None, **kwargs): "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='../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 = "%s-%s" % (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 = "%s-%s" % (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 = "%s-%s" % (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)
def _changeform_view(self, request, object_id, form_url, extra_context): add = object_id is None model = self.model opts = model._meta model_form = self.get_form(request) formsets = [] if add: if not self.has_add_permission(request): raise PermissionDenied obj = None else: obj = self.get_object(request, unquote(object_id)) if request.method == 'POST': if not self.has_change_permission(request, obj): raise PermissionDenied else: if not self.has_view_or_change_permission(request, obj): raise PermissionDenied if obj is None: return self._get_obj_does_not_exist_redirect( request, opts, object_id) if request.method == 'POST': form = model_form(request.POST, request.FILES, instance=obj) form_validated = form.is_valid() if form_validated: new_object = self.save_form(request, form, change=not add) else: new_object = form.instance prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(request): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: 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) formsets.append(formset) formsets = _remove_blank_reverse_inlines(new_object, formsets) if form_validated and not formsets: self.save_model(request, new_object, form, change=not add) self.save_related(request, form, formsets, change=not add) form.save_m2m() return self.response_add(request, new_object) elif form_validated and all_valid(formsets): # Here is the modified code. for formset, inline in zip(formsets, self.get_inline_instances(request)): if not isinstance(inline, ReverseInlineModelAdmin): continue # The idea or this piece is coming from https://stackoverflow.com/questions/50910152/inline-formset-returns-empty-list-on-save. # Without this, formset.save() was returning None for forms that # haven't been modified forms = [f for f in formset] if not forms: continue obj = forms[0].save() setattr(new_object, inline.parent_fk_name, obj) self.save_model(request, new_object, form, change=not add) self.save_related(request, form, formsets, change=not add) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=not add) # self.log_addition(request, new_object) 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(",") if add: form = model_form(initial=initial) prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(request): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=self.model(), prefix=prefix) formsets.append(formset) else: form = model_form(instance=obj) formsets, inline_instances = self._create_formsets(request, obj, change=True) readonly_fields = self.get_readonly_fields(request, obj) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields, readonly_fields=readonly_fields, 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)) inline_admin_formset = helpers.InlineAdminFormSet( inline, formset, fieldsets, readonly_fields=readonly_fields) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media # Inherit the default context from admin_site context = self.admin_site.each_context(request) reverse_admin_context = { 'title': _(('Change %s', 'Add %s')[add]) % force_text(opts.verbose_name), 'adminform': adminForm, # 'is_popup': '_popup' in request.REQUEST, 'is_popup': False, 'original': obj, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), # 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, } context.update(reverse_admin_context) context.update(extra_context or {}) return self.render_change_form( request, context, form_url=form_url, add=add, change=not add, )
def valid_forms(self, result): return all_valid(self.formsets) and result
def render_revision_form(self, request, obj, version, context, revert=False, recover=False): """Renders the object revision form.""" model = self.model opts = model._meta object_id = obj.pk # Generate the model form. ModelForm = self.get_form(request, obj) formsets = [] if request.method == "POST": # This section is copied directly from the model admin change view # method. Maybe one day there will be a hook for doing this better. form = ModelForm(request.POST, request.FILES, instance=obj, initial=self.get_revision_form_data(request, obj, version)) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=True) # HACK: If the value of a file field is None, remove the file from the model. for field in new_object._meta.fields: if isinstance(field, models.FileField) and form.cleaned_data[field.name] is None: setattr(new_object, field.name, None) else: form_validated = False new_object = obj prefixes = {} for FormSet, inline in zip(self.get_formsets(request, new_object), self.inline_instances): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix, queryset=inline.queryset(request)) # Hack the formset to stuff in the new data. related_versions = self.get_related_versions(obj, version, FormSet) formset.related_versions = related_versions new_forms = formset.forms[:len(related_versions)] for formset_form in formset.forms[len(related_versions):]: if formset_form.fields["DELETE"].clean(formset_form._raw_value("DELETE")): new_forms.append(formset_form) formset.forms = new_forms def total_form_count_hack(count): return lambda: count formset.total_form_count = total_form_count_hack(len(new_forms)) # Add this hacked formset to the form. formsets.append(formset) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, change=True) form.save_m2m() for formset in formsets: # HACK: If the value of a file field is None, remove the file from the model. related_objects = formset.save(commit=False) for related_obj, related_form in zip(related_objects, formset.saved_forms): for field in related_obj._meta.fields: if isinstance(field, models.FileField) and related_form._raw_value(field.name) is None: related_info = formset.related_versions.get(unicode(related_obj.pk)) if related_info: setattr(related_obj, field.name, related_info.field_dict[field.name]) related_obj.save() formset.save_m2m() change_message = _(u"Reverted to previous version, saved on %(datetime)s") % {"datetime": format(version.revision.date_created, _(settings.DATETIME_FORMAT))} self.log_change(request, new_object, change_message) self.message_user(request, _(u'The %(model)s "%(name)s" was reverted successfully. You may edit it again below.') % {"model": force_unicode(opts.verbose_name), "name": unicode(obj)}) # Redirect to the model change form. if revert: return HttpResponseRedirect("../../") elif recover: return HttpResponseRedirect("../../%s/" % object_id) else: assert False else: # This is a mutated version of the code in the standard model admin # change_view. Once again, a hook for this kind of functionality # would be nice. Unfortunately, it results in doubling the number # of queries required to construct the formets. form = ModelForm(instance=obj, initial=self.get_revision_form_data(request, obj, version)) prefixes = {} for FormSet, inline in zip(self.get_formsets(request, obj), self.inline_instances): # This code is standard for creating the formset. prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix, queryset=inline.queryset(request)) # Now we hack it to push in the data from the revision! initial = [] related_versions = self.get_related_versions(obj, version, FormSet) for related_obj in formset.queryset: if unicode(related_obj.pk) in related_versions: initial.append(related_versions.pop(unicode(related_obj.pk)).field_dict) else: initial_data = model_to_dict(related_obj) initial_data["DELETE"] = True initial.append(initial_data) for related_version in related_versions.values(): initial_row = related_version.field_dict pk_name = ContentType.objects.get_for_id(related_version.content_type_id).model_class()._meta.pk.name del initial_row[pk_name] initial.append(initial_row) # Reconstruct the forms with the new revision data. formset.initial = initial formset.forms = [formset._construct_form(n) for n in xrange(len(initial))] def total_form_count_hack(count): return lambda: count formset.total_form_count = total_form_count_hack(len(initial)) # Add this hacked formset to the form. formsets.append(formset) # Generate admin form helper. 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 # Generate formset helpers. inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, 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) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media # Generate the context. context.update({"adminform": adminForm, "object_id": object_id, "original": obj, "is_popup": False, "media": mark_safe(media), "inline_admin_formsets": inline_admin_formsets, "errors": helpers.AdminErrorList(form, formsets), "app_label": opts.app_label, "add": False, "change": True, "revert": revert, "recover": recover, "has_add_permission": self.has_add_permission(request), "has_change_permission": self.has_change_permission(request, obj), "has_delete_permission": self.has_delete_permission(request, obj), "has_file_field": True, "has_absolute_url": False, "ordered_objects": opts.get_ordered_objects(), "form_url": mark_safe(request.path), "opts": opts, "content_type_id": ContentType.objects.get_for_model(self.model).id, "save_as": False, "save_on_top": self.save_on_top, "changelist_url": reverse("%s:%s_%s_changelist" % (self.admin_site.name, opts.app_label, opts.module_name)), "change_url": reverse("%s:%s_%s_change" % (self.admin_site.name, opts.app_label, opts.module_name), args=(obj.pk,)), "history_url": reverse("%s:%s_%s_history" % (self.admin_site.name, opts.app_label, opts.module_name), args=(obj.pk,)), "recoverlist_url": reverse("%s:%s_%s_recoverlist" % (self.admin_site.name, opts.app_label, opts.module_name))}) # Render the form. if revert: form_template = self.revision_form_template or self._get_template_list("revision_form.html") elif recover: form_template = self.recover_form_template or self._get_template_list("recover_form.html") else: assert False return render_to_response(form_template, context, template.RequestContext(request))
def add_view(self, request, extra_context=None, form_url=None): opts = self.model._meta if not self.has_add_permission(request): raise PermissionDenied ModelForm = self.get_form(request, fields=None, formfield_callback=self._formfield_callback(request=request), form=self.form ) inline_formset_types = self._get_inline_formset_types(request) formsets = [] if request.method == 'POST': model_form = ModelForm(request.POST, request.FILES) if model_form.is_valid(): form_validated = True new_object = self.save_form(request, model_form, change=False) else: form_validated = False new_object = self.model() inline_formsets = [ formset_class(request.POST, request.FILES, instance=new_object, prefix=content_type.__name__.lower()) for content_type, formset_class in inline_formset_types] prefixes = {} for FormSet, inline in zip(self.get_formsets(request), self.inline_instances): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(data=request.POST, files=request.FILES, instance=new_object, save_as_new=request.POST.has_key('_saveasnew'), prefix=prefix, queryset=inline.queryset(request)) formsets.append(formset) if all_valid(inline_formsets+formsets) and form_validated: self.save_model(request, new_object, model_form, change=False) model_form.save_m2m() for formset in inline_formsets: formset.save() for formset in formsets: self.save_formset(request, model_form, formset, change=False) msg = _('The %(name)s "%(obj)s" was added successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(new_object)} if request.POST.has_key("_continue"): self.message_user(request, msg + ' ' + _("You may edit it again below.")) return HttpResponseRedirect('../%s/' % new_object.pk) elif request.POST.has_key('_addanother'): self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) return HttpResponseRedirect("../add/") else: self.message_user(request, msg) return HttpResponseRedirect("../") else: initial = dict(request.GET.items()) model_form = ModelForm(initial=initial) inline_formsets = [ formset_class(prefix=content_type.__name__.lower()) for content_type, formset_class in inline_formset_types] prefixes = {} for FormSet, inline in zip(self.get_formsets(request), self.inline_instances): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=self.model(), prefix=prefix, queryset=inline.queryset(request)) formsets.append(formset) # Prepare mapping of content types to their prettified names content_types = [] for content_type in self.model._feincms_content_types: content_name = content_type._meta.verbose_name content_types.append((content_name, content_type.__name__.lower())) context = {} #media = self.media + model_form.media adminForm = helpers.AdminForm(model_form, list(self.get_fieldsets(request)), self.prepopulated_fields, self.get_readonly_fields(request), model_admin=self) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets, model_admin=self) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media if hasattr(self.model, '_feincms_templates'): if 'template_key' not in self.show_on_top: self.show_on_top = ['template_key'] + list(self.show_on_top) context['available_templates'] = self.model._feincms_templates if hasattr(self.model, 'parent'): context['has_parent_attribute'] = True context.update({ 'has_add_permission': self.has_add_permission(request), 'has_change_permission': self.has_change_permission(request), 'has_delete_permission': self.has_delete_permission(request), 'add': True, 'change': False, 'title': _('Add %s') % force_unicode(opts.verbose_name), 'opts': opts, 'object': self.model(), 'object_form': model_form, 'adminform': adminForm, 'inline_formsets': inline_formsets, 'inline_admin_formsets': inline_admin_formsets, 'content_types': content_types, 'top_fields': [model_form[field] for field in self.show_on_top], 'settings_fields': [field for field in model_form if field.name not in self.show_on_top], 'media': media, 'errors': helpers.AdminErrorList(model_form, inline_formsets), 'FEINCMS_ADMIN_MEDIA': settings.FEINCMS_ADMIN_MEDIA, 'FEINCMS_ADMIN_MEDIA_HOTLINKING': settings.FEINCMS_ADMIN_MEDIA_HOTLINKING, }) return self.render_item_editor(request, None, context)
def post(self, request, *args, **kwargs): self.construct_formsets() if all_valid(self.formsets_instances): return self.formsets_valid() else: return self.formsets_invalid()
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 model_form = self.get_form(request) formsets = [] if request.method == 'POST': form = model_form(request.POST, request.FILES) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=False) else: form_validated = False new_object = self.model() prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(request): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: 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) formsets.append(formset) if all_valid(formsets) and form_validated: # Here is the modified code. for formset, inline in zip(formsets, self.get_inline_instances(request)): if not isinstance(inline, ReverseInlineModelAdmin): continue obj = formset.save()[0] setattr(new_object, inline.parent_fk_name, obj) self.save_model(request, new_object, form, change=False) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=False) # self.log_addition(request, new_object) 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 = model_form(initial=initial) prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(request): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=self.model(), prefix=prefix) formsets.append(formset) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields) 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)) inline_admin_formset = helpers.InlineAdminFormSet( inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media context = { 'title': _('Add %s') % force_text(opts.verbose_name), 'adminform': adminForm, # 'is_popup': '_popup' in request.REQUEST, 'is_popup': False, 'show_delete': False, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), # 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, form_url=form_url, add=True)
def mass_change_view(self, request, comma_separated_object_ids, extra_context=None): """The 'mass change' admin view for this model.""" global new_object model = self.model opts = model._meta general_error = None # Allow model to hide some fields for mass admin exclude_fields = getattr(self.admin_obj, "massadmin_exclude", ()) queryset = getattr(self.admin_obj, "massadmin_queryset", self.get_queryset)(request) object_ids = comma_separated_object_ids.split(',') object_id = object_ids[0] try: obj = queryset.get(pk=unquote(object_id)) except model.DoesNotExist: obj = None # TODO It's necessary to check permission and existence for all object 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_text(opts.verbose_name), 'key': escape(object_id) }) ModelForm = self.get_form(request, obj) formsets = [] errors, errors_list = None, None mass_changes_fields = request.POST.getlist("_mass_change") if request.method == 'POST': # commit only when all forms are valid try: with transaction.atomic(): objects_count = 0 changed_count = 0 objects = queryset.filter(pk__in=object_ids) for obj in objects: objects_count += 1 form = ModelForm(request.POST, request.FILES, instance=obj) exclude = [] for fieldname, field in list(form.fields.items()): if fieldname not in mass_changes_fields: exclude.append(fieldname) for exclude_fieldname in exclude: del form.fields[exclude_fieldname] 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 in get_formsets(self, request, new_object): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) if prefix in mass_changes_fields: formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix) formsets.append(formset) if all_valid(formsets) and form_validated: # self.admin_obj.save_model(request, new_object, form, change=True) 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) changed_count += 1 if changed_count == objects_count: return self.response_change(request, new_object) else: errors = form.errors errors_list = helpers.AdminErrorList(form, formsets) # Raise error for rollback transaction in atomic block raise ValidationError("Not all forms is correct") except: general_error = sys.exc_info()[1] form = ModelForm(instance=obj) form._errors = errors prefixes = {} for FormSet in get_formsets(self, request, obj): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields, self.get_readonly_fields(request, obj), model_admin=self.admin_obj) media = self.media + adminForm.media # We don't want the user trying to mass change unique fields! unique_fields = [] try: # Django >= 1.9 fields = model._meta.get_fields() except: fields = model._meta.get_all_field_names() for field_name in fields: try: field = model._meta.get_field(field_name) if field.unique: unique_fields.append(field_name) except: pass # Buggy! Use at your own risk #inline_admin_formsets = [] # for inline, formset in zip(self.inline_instances, formsets): # fieldsets = list(inline.get_fieldsets(request, obj)) # inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) # inline_admin_formsets.append(inline_admin_formset) # media = media + inline_admin_formset.media context = { 'title': _('Change %s') % force_text(opts.verbose_name), 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'unique_fields': unique_fields, 'exclude_fields': exclude_fields, 'is_popup': '_popup' in request.GET or '_popup' in request.POST, 'media': mark_safe(media), #'inline_admin_formsets': inline_admin_formsets, 'errors': errors_list, 'general_error': general_error, 'app_label': opts.app_label, 'object_ids': comma_separated_object_ids, 'mass_changes_fields': mass_changes_fields, } context.update(extra_context or {}) return self.render_mass_change_form(request, context, change=True, obj=obj)
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='../add/') formsets = [] form = self.get_main_view_form(request, obj) if request.method == 'POST': if form.is_valid(): form_validated = True instance = self.save_form(request, form, change=True) else: form_validated = False instance = obj else: instance = obj for formset in self.get_formset_instances(request, instance, is_new=False): formsets.append(formset) if request.method == 'POST' and all_valid(formsets) and form_validated: self.save_view_formsets(request, instance, form, formsets, is_new=False) return self.response_change(request, instance) if hasattr(self, 'get_prepopulated_field'): # Django 1.4 prepopulated_fields = self.get_prepopulated_field(request) else: prepopulated_fields = self.prepopulated_fields adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), prepopulated_fields, self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media inline_admin_formsets = [] for inline_admin_formset in self.get_inline_admin_formsets( request, formsets, obj): inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media for nested in getattr(inline_admin_formset, 'inlines', []): media += nested.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), 'root_path': reverse('admin:index'), 'app_label': opts.app_label, } if hasattr(self, 'get_preserved_filters'): # Django 1.6 context['preserved_filters'] = self.get_preserved_filters(request) context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url)
def changeform_view(self, request, object_id=None, form_url='', extra_context=None): to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField( "The field %s cannot be referenced." % to_field) model = self.model opts = model._meta if request.method == 'POST' and '_saveasnew' in request.POST: object_id = None add = object_id is None if add: if not self.has_add_permission(request): raise PermissionDenied obj = None else: obj = self.get_object(request, unquote(object_id), to_field) 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_text(opts.verbose_name), 'key': escape(object_id) }) ModelForm = self.get_form(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=not add) else: form_validated = False new_object = form.instance formsets, inline_instances = self._create_formsets(request, new_object, change=not add) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, not add) self.save_related(request, form, formsets, not add) change_message = self.construct_change_message( request, form, formsets, add) if add: self.log_addition(request, new_object, change_message) return self.response_add(request, new_object) else: self.log_change(request, new_object, change_message) return self.response_change(request, new_object) else: form_validated = False else: if add: initial = self.get_changeform_initial_data(request) form = ModelForm(initial=initial) formsets, inline_instances = self._create_formsets( request, form.instance, change=False) else: form = ModelForm(instance=obj) formsets, inline_instances = self._create_formsets(request, obj, change=True) adminForm = helpers.AdminForm(form, list(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_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj) for inline_formset in inline_formsets: media = media + inline_formset.media context = dict( self.admin_site.each_context(request), title=(_('Add %s') if add else _('Change %s')) % force_text(opts.verbose_name), adminform=adminForm, object_id=object_id, original=obj, is_popup=(IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), to_field=to_field, media=media, inline_admin_formsets=inline_formsets, errors=helpers.AdminErrorList(form, formsets), preserved_filters=self.get_preserved_filters(request), ) # Hide the "Save" and "Save and continue" buttons if "Save as New" was # previously chosen to prevent the interface from getting confusing. if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST: context['show_save'] = False context['show_save_and_continue'] = False # Use the change template instead of the add template. add = False context.update(extra_context or {}) return self.render_change_form(request, context, add=add, change=not add, 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 formsets = [] form = self.get_main_view_form(request) if request.method == 'POST': if form.is_valid(): new_object = self.save_form(request, form, change=False) form_validated = True else: form_validated = False new_object = self.model() else: new_object = self.model() for formset in self.get_formset_instances(request, new_object, is_new=True): formsets.append(formset) if request.method == 'POST' and all_valid(formsets) and form_validated: self.save_view_formsets(request, new_object, form, formsets, is_new=True) return self.response_add(request, new_object) if hasattr(self, 'get_prepopulated_fields'): # Django 1.4 prepopulated_fields = self.get_prepopulated_fields(request) else: prepopulated_fields = self.prepopulated_fields adminForm = helpers.AdminForm(form, self.get_fieldsets(request), prepopulated_fields, self.get_readonly_fields(request), model_admin=self) media = self.media + adminForm.media inline_admin_formsets = [] for inline_admin_formset in self.get_inline_admin_formsets( request, formsets): inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media for nested in getattr(inline_admin_formset, 'inlines', []): media += nested.media context = { 'title': _('Add %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'is_popup': '_popup' in request.REQUEST, 'show_delete': False, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': reverse('admin:index'), 'app_label': opts.app_label, } if hasattr(self, 'get_preserved_filters'): # Django 1.6 context['preserved_filters'] = self.get_preserved_filters(request) context.update(extra_context or {}) return self.render_change_form(request, context, form_url=form_url, add=True)
def _django_change_view(self, request, object_id, extra_context=None): "The 'change' admin view for this model." model = self.model opts = model._meta obj = self.get_object(request, unquote(object_id)) previous_template = obj.template # STOAT: Save previous template 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 = {} if previous_template == new_object.template: # STOAT: Template check for FormSet, inline in zip( self.get_formsets(request, new_object), self._create_inlines(obj)): # STOAT: _create_inlines prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix, queryset=inline.queryset(request)) formsets.append(formset) 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._create_inlines(obj)): # STOAT: _create_inlines prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (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._create_inlines(obj), formsets): # STOAT: _create_inlines 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) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media media = media + extra_context.pop('media') # STOAT 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), 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj)
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 = [] if request.method == 'POST': form = ModelForm(request.POST, request.FILES) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=False) else: form_validated = False new_object = self.model() for FormSet in self.get_formsets(request): formset = FormSet( data=request.POST, files=request.FILES, instance=new_object, save_as_new=request.POST.has_key("_saveasnew")) formsets.append(formset) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, change=False) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=False) self.log_addition(request, new_object) 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) for FormSet in self.get_formsets(request): formset = FormSet(instance=self.model()) formsets.append(formset) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet( inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media context = { 'title': _('Add %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'is_popup': request.REQUEST.has_key('_popup'), 'show_delete': False, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, add=True)
def _changeform_view(self, request, object_id, form_url, extra_context): to_field = request.POST.get('_to_field', request.GET.get('_to_field')) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field) model = self.model opts = model._meta if request.method == 'POST' and '_saveasnew' in request.POST: object_id = None add = object_id is None if add: if not self.has_add_permission(request): raise PermissionDenied obj = None else: obj = self.get_object(request, unquote(object_id), to_field) if not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: return self._get_obj_does_not_exist_redirect(request, opts, object_id) ModelForm = self.get_form(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=not add) else: form_validated = False new_object = form.instance formsets, inline_instances = self._create_formsets(request, new_object, change=not add) # ----- NUMBER OF CANDIDATES number_candidates = 0 if all_valid(formsets): for formset in formsets: for f in formset: cd = f.cleaned_data candidate = cd.get('president_candidate') or cd.get('congress_candidate') delete = cd.get('DELETE') if candidate: number_candidates += 1 if delete: number_candidates -= 1 valid_number_candidates_congress = True if number_candidates > 350 or number_candidates <= 0: valid_number_candidates_congress = False # Message users if not valid_number_candidates_congress: msg = 'The number of candidates must be 350 or less as well as having at least one candidate. There are now {} candidates.'.format(number_candidates) self.message_user(request, msg, messages.WARNING) # ----- END NUMBER OF CANDIDATES # ----- GENDER BALANCE LOAD CHECK women_number = 0 men_number = 0 if all_valid(formsets): for formset in formsets: for f in formset: cd = f.cleaned_data genre = cd.get('gender') delete = cd.get('DELETE') if genre == 'H': men_number += 1 elif genre == 'M': women_number += 1 if delete: if genre == 'H': men_number -= 1 elif genre == 'M': women_number -= 1 valid_genre_balance = True if women_number+men_number == 0: women_balance = 0 men_balance = 0 else: women_balance = (women_number/(women_number+men_number)) men_balance = (men_number/(women_number+men_number)) if women_balance < 0.4 or men_balance < 0.4 : valid_genre_balance = False # Message users if not valid_genre_balance: msg = 'The number of women candidates and the number of men candidates must be at least a 40% of the total candidates. Women: {}%, Men:{}%'.format(women_balance*100, men_balance*100) self.message_user(request, msg, messages.WARNING) # ----- END GENDER BALANCE LOAD CHECK if all_valid(formsets) and form_validated and valid_number_candidates_congress and valid_genre_balance: self.save_model(request, new_object, form, not add) self.save_related(request, form, formsets, not add) change_message = self.construct_change_message(request, form, formsets, add) if add: self.log_addition(request, new_object, change_message) return self.response_add(request, new_object) else: self.log_change(request, new_object, change_message) return self.response_change(request, new_object) else: form_validated = False else: if add: initial = self.get_changeform_initial_data(request) form = ModelForm(initial=initial) formsets, inline_instances = self._create_formsets(request, form.instance, change=False) else: form = ModelForm(instance=obj) formsets, inline_instances = self._create_formsets(request, obj, change=True) adminForm = helpers.AdminForm( form, list(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_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj) for inline_formset in inline_formsets: media = media + inline_formset.media context = dict( self.admin_site.each_context(request), title=(_('Add %s') if add else _('Change %s')) % opts.verbose_name, adminform=adminForm, object_id=object_id, original=obj, is_popup=('_popup' in request.POST or '_popup' in request.GET), to_field=to_field, media=media, inline_admin_formsets=inline_formsets, errors=helpers.AdminErrorList(form, formsets), preserved_filters=self.get_preserved_filters(request), ) # Hide the "Save" and "Save and continue" buttons if "Save as New" was # previously chosen to prevent the interface from getting confusing. if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST: context['show_save'] = False context['show_save_and_continue'] = False # Use the change template instead of the add template. add = False context.update(extra_context or {}) return self.render_change_form(request, context, add=add, change=not add, obj=obj, form_url=form_url)
def change_view(self, request, object_id, extra_context=None): """ Like the original change_view from ModelAdmin. Alterations are marked with # ----start # ----end """ "The 'change' admin view for this model." model = self.model opts = model._meta try: obj = self.queryset(request).get(pk=unquote(object_id)) except model.DoesNotExist: # Don't raise Http404 just yet, because we haven't checked # permissions yet. We don't want an unauthenticated user to be able # to determine whether a given object exists. obj = None 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 request.POST.has_key("_saveasnew"): 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 in self.get_formsets(request, new_object): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix) formsets.append(formset) 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 in self.get_formsets(request, obj): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) # --start-- adminForm = Tabset(form, self.tabs, self.prepopulated_fields) # --original-- # adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields) # --end-- media = self.media + adminForm.media # --start-- inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) tab = adminForm.get_tab_that_has_inline(inline.__class__.__name__) if not tab==None: tab.inlines.append(inline_admin_formset) else: inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media # --original-- ''' inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media ''' # --end-- context = { 'title': _('Change %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'is_popup': request.REQUEST.has_key('_popup'), 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj)
def change_view(self, request, object_id, extra_context=None): self.model._needs_content_types() # Recognize frontend editing requests # This is done here so that the developer does not need to add additional entries to # urls.py or something... res = FRONTEND_EDITING_MATCHER.search(object_id) if res: return self._frontend_editing_view(request, res.group(1), res.group(2), res.group(3)) opts = self.model._meta try: obj = self.model._default_manager.get(pk=unquote(object_id)) except self.model.DoesNotExist: raise Http404 if not self.has_change_permission(request, obj): raise PermissionDenied if "revision" in request.GET: from reversion.models import Revision try: revision = Revision.objects.get(pk=request.GET['revision']) except Revision.DoesNotExist: raise Http404 self.message_user(request, _('Click save to replace the current content with this version')) else: revision = None ModelForm = self.get_form( request, obj, # NOTE: Fields *MUST* be set to None to avoid breaking # django.contrib.admin.option.ModelAdmin's default get_form() # will generate a very abbreviated field list which will cause # KeyErrors during clean() / save() fields=None, formfield_callback=self._formfield_callback(request=request), form=self.form ) # generate a formset type for every concrete content type inline_formset_types = self._get_inline_formset_types(request) formsets = [] if request.method == 'POST': FORM_DATA = {} model_form = ModelForm(request.POST, request.FILES, instance=obj) inline_formsets = [ formset_class(request.POST, request.FILES, instance=obj, prefix=content_type.__name__.lower()) for content_type, formset_class in inline_formset_types] if model_form.is_valid(): form_validated = True new_object = self.save_form(request, model_form, change=True) else: form_validated = False new_object = obj prefixes = {} for FormSet in self.get_formsets(request, new_object): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix) formsets.append(formset) if all_valid(inline_formsets+formsets) and form_validated: #model_form.save(commit=False) model_form.save_m2m() for formset in inline_formsets: formset.save() #model_form.save(commit=True) self.save_model(request, new_object, model_form, change=True) for formset in formsets: self.save_formset(request, model_form, formset, change=True) msg = _('The %(name)s "%(obj)s" was changed successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj)} if request.POST.has_key("_continue"): self.message_user(request, msg + ' ' + _("You may edit it again below.")) return HttpResponseRedirect('.') elif request.POST.has_key('_addanother'): self.message_user(request, msg + ' ' + (_("You may add another %s below.") % force_unicode(opts.verbose_name))) return HttpResponseRedirect("../add/") else: self.message_user(request, msg) return HttpResponseRedirect("../") elif revision: FORM_DATA = {} total_forms = dict( [(ct.__name__.lower(), 0) for ct in self.model._feincms_content_types] ) for version in revision.version_set.all().select_related("content_type"): if version.object_version.object == obj: FORM_DATA.update(version.field_dict) continue version_prefix = "%s-%s" % ( version.content_type.model, total_forms[version.content_type.model] ) for k, v in version.field_dict.items(): form_key = "%s-%s" % (version_prefix, k) assert form_key not in FORM_DATA FORM_DATA[form_key] = v # defaultdict would be cleaner but this works with Python 2.4: total_forms[version.content_type.model] += 1 for k, v in total_forms.items(): FORM_DATA["%s-INITIAL_FORMS" % k] = v # TOTAL FORMS should be one for each actual object and one for # the "Add new" feature. We'll bump the total up if we actually # have existing content: if v: FORM_DATA["%s-TOTAL_FORMS" % k] = v + 1 else: FORM_DATA["%s-TOTAL_FORMS" % k] = 0 # BUG: This somehow does not correctly initialize the initial form for adding new content correctly model_form = ModelForm(FORM_DATA, instance=obj) inline_formsets = [ formset_class(FORM_DATA, instance=obj, prefix=content_type.__name__.lower()) for content_type, formset_class in inline_formset_types ] prefixes = {} for FormSet in self.get_formsets(request, obj): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) else: model_form = ModelForm(instance=obj) inline_formsets = [ formset_class(instance=obj, prefix=content_type.__name__.lower()) for content_type, formset_class in inline_formset_types ] prefixes = {} for FormSet in self.get_formsets(request, obj): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) # Prepare mapping of content types to their prettified names content_types = [] for content_type in self.model._feincms_content_types: content_name = content_type._meta.verbose_name content_types.append((content_name, content_type.__name__.lower())) context = {} adminForm = helpers.AdminForm(model_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.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media if hasattr(self.model, '_feincms_templates'): if 'template_key' not in self.show_on_top: self.show_on_top = ['template_key'] + list(self.show_on_top) context['available_templates'] = self.model._feincms_templates if hasattr(self.model, 'parent'): context['has_parent_attribute'] = True context.update({ 'has_add_permission': self.has_add_permission(request), 'has_change_permission': self.has_change_permission(request, obj=obj), 'has_delete_permission': self.has_delete_permission(request, obj=obj), 'add': False, 'change': obj.pk is not None, 'title': _('Change %s') % force_unicode(opts.verbose_name), 'opts': opts, 'object': obj, 'object_form': model_form, 'adminform': adminForm, 'inline_formsets': inline_formsets, 'inline_admin_formsets': inline_admin_formsets, 'content_types': content_types, 'top_fields': [model_form[field] for field in self.show_on_top], 'settings_fields': [field for field in model_form if field.name not in self.show_on_top], 'media': media, 'errors': helpers.AdminErrorList(model_form, inline_formsets), 'FEINCMS_ADMIN_MEDIA': settings.FEINCMS_ADMIN_MEDIA, 'FEINCMS_ADMIN_MEDIA_HOTLINKING': settings.FEINCMS_ADMIN_MEDIA_HOTLINKING, }) return self.render_item_editor(request, obj, context)
def get_add_view_context(self, request, form_url): model = self.model opts = model._meta if not self.has_add_permission(request): raise PermissionDenied ModelForm = self.get_form(request) formsets = [] context = {} if request.method == 'POST': error_dict = {} form = ModelForm(request.POST.copy(), request.FILES) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=False) else: for e in form.errors: error_dict[u"id_%s" % e] = [ u"%s" % ee for ee in form.errors[e] ] form_validated = False new_object = self.model() prefixes = {} for FormSet in self.get_formsets(request): prefix = FormSet.get_default_prefix() prefix_no = prefixes.get(prefix, 0) prefixes[prefix] = prefix_no + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(data=request.POST.copy(), files=request.FILES, instance=new_object, save_as_new=request.POST.has_key("_saveasnew"), prefix=prefix) if not formset.is_valid(): for e in formset.errors[prefix_no]: error_dict[u"id_%s-%d-%s" % (prefix, prefix_no, e)] = [u"%s" % ee for ee in formset.errors[prefix_no][e]] formsets.append(formset) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, change=False) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=False) self.log_addition(request, new_object) self.response_add(request, new_object) context.update({ 'object': new_object, 'object_added': True, }) else: context.update({ 'error_dict': error_dict, }) 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 FieldDoesNotExist: continue if isinstance(f, ManyToManyField): initial[k] = initial[k].split(",") form = ModelForm(initial=initial) prefixes = {} for FormSet in self.get_formsets(request): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=self.model(), prefix=prefix) formsets.append(formset) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet(inline, formset, fieldsets) inline_admin_formset = self.get_inline_admin_formset(inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media context.update({ 'title': _('Add %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'is_popup': request.REQUEST.has_key('_popup'), 'show_delete': False, 'media': media, 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, }) context['raw_form'] = form return context
def mass_change_view(self, request, comma_separated_object_ids, extra_context=None): """The 'mass change' admin view for this model.""" global new_object model = self.model opts = model._meta object_ids = comma_separated_object_ids.split(',') object_id = object_ids[0] try: obj = self.queryset(request).get(pk=unquote(object_id)) except model.DoesNotExist: obj = None 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 request.POST.has_key("_saveasnew"): return self.add_view(request, form_url='../add/') ModelForm = self.get_form(request, obj) formsets = [] if request.method == 'POST': objects_count = 0 changed_count = 0 objects = self.queryset(request).filter(pk__in=object_ids) for obj in objects: objects_count += 1 form = ModelForm(request.POST, request.FILES, instance=obj) exclude = [] for fieldname, field in form.fields.items(): mass_change_checkbox = '_mass_change_%s' % fieldname if not (request.POST.has_key(mass_change_checkbox) and request.POST[mass_change_checkbox] == 'on'): exclude.append(fieldname) for exclude_fieldname in exclude: del form.fields[exclude_fieldname] 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 in self.get_formsets(request, new_object): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) mass_change_checkbox = '_mass_change_%s' % prefix if request.POST.has_key( mass_change_checkbox ) and request.POST[mass_change_checkbox] == 'on': formset = FormSet(request.POST, request.FILES, instance=new_object, prefix=prefix) formsets.append(formset) if all_valid(formsets) and form_validated: self.admin_obj.save_model(request, new_object, form, change=True) # 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) changed_count += 1 if changed_count == objects_count: return self.response_change(request, new_object) else: raise Exception( 'Some of the selected objects could\'t be changed.') else: form = ModelForm(instance=obj) prefixes = {} for FormSet in self.get_formsets(request, obj): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=obj, prefix=prefix) formsets.append(formset) adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet( inline, formset, fieldsets) 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': request.REQUEST.has_key('_popup'), 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': self.admin_site.root_path, 'app_label': opts.app_label, 'object_ids': comma_separated_object_ids, } context.update(extra_context or {}) return self.render_mass_change_form(request, context, change=True, obj=obj)
def _changeform_view(self, request, object_id, form_url, extra_context): to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField("The field %s cannot be referenced." % to_field) model = self.model opts = model._meta if request.method == 'POST' and '_saveasnew' in request.POST: object_id = None add = object_id is None if add: if not self.has_add_permission(request): raise PermissionDenied obj = None else: obj = self.get_object(request, unquote(object_id), to_field) if request.method == 'POST': if not self.has_change_permission(request, obj): raise PermissionDenied else: if not self.has_view_or_change_permission(request, obj): raise PermissionDenied if obj is None: return self._get_obj_does_not_exist_redirect(request, opts, object_id) ModelForm = self.get_form(request, obj, change=not add) if request.method == 'POST': form = ModelForm(request.POST, request.FILES, instance=obj) form_validated = form.is_valid() if form_validated: new_object = self.save_form(request, form, change=not add) else: new_object = form.instance formsets, inline_instances = self._create_formsets(request, new_object, change=not add) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, not add) self.save_related(request, form, formsets, not add) change_message = self.construct_change_message(request, form, formsets, add) if add: self.log_addition(request, new_object, change_message) return self.response_add(request, new_object) else: self.log_change(request, new_object, change_message) return self.response_change(request, new_object) else: form_validated = False else: if add: initial = self.get_changeform_initial_data(request) form = ModelForm(initial=initial) formsets, inline_instances = self._create_formsets(request, form.instance, change=False) else: # Changed # 因为ArticleAdminForm中有Article没有的字段,这些字段的值不会变填充 # field_init_value就是用于给这些字段填充值用的 form = ModelForm(instance=obj, initial=self.field_init_value) formsets, inline_instances = self._create_formsets(request, obj, change=True) if not add and not self.has_change_permission(request, obj): readonly_fields = flatten_fieldsets(self.get_fieldsets(request, obj)) else: readonly_fields = self.get_readonly_fields(request, obj) adminForm = helpers.AdminForm( form, list(self.get_fieldsets(request, obj)), # Clear prepopulated fields on a view-only form to avoid a crash. self.get_prepopulated_fields(request, obj) if add or self.has_change_permission(request, obj) else {}, readonly_fields, model_admin=self) media = self.media + adminForm.media inline_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj) for inline_formset in inline_formsets: media = media + inline_formset.media if add: title = _('Add %s') elif self.has_change_permission(request, obj): title = _('Change %s') else: title = _('View %s') context = { **self.admin_site.each_context(request), 'title': title % opts.verbose_name, 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'is_popup': IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET, 'to_field': to_field, 'media': media, 'inline_admin_formsets': inline_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'preserved_filters': self.get_preserved_filters(request), } # Hide the "Save" and "Save and continue" buttons if "Save as New" was # previously chosen to prevent the interface from getting confusing. if request.method == 'POST' and not form_validated and "_saveasnew" in request.POST: context['show_save'] = False context['show_save_and_continue'] = False # Use the change template instead of the add template. add = False context.update(extra_context or {}) return self.render_change_form(request, context, add=add, change=not add, obj=obj, form_url=form_url)
def change_view(self, request, object_id, 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 request.POST.has_key("_saveasnew"): 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 formsets, inline_admin_formsets, media = \ self._nested_formsets(request, self, new_object, lambda FormSet, req, admin, inst, prefix, qs: FormSet(data=req.POST, files=req.FILES, instance=inst, prefix=prefix, queryset=qs)) 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) formsets, inline_admin_formsets, media = \ self._nested_formsets(request, self, obj, lambda FormSet, req, admin, inst, prefix, qs: FormSet(instance=inst, prefix=prefix, queryset=qs)) adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields, self.get_readonly_fields(request, obj), model_admin=self) new_media = self.media + adminForm.media for m in media: new_media = new_media + m media = new_media context = { 'title': _('Change %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'is_popup': ('_popup' in request.POST or '_popup' in request.GET), 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'app_label': opts.app_label, 'level': 1, } context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj)
def clone_view(self, request, object_id, form_url='', extra_context=None): opts = self.model._meta if not self.has_add_permission(request): raise PermissionDenied original_obj = self.get_object(request, unquote(object_id)) if original_obj is None: raise Http404( _('{name} object with primary key {key} does not exist.'. format(name=force_text(opts.verbose_name), key=repr(escape(object_id))))) ModelForm = self.get_form(request) formsets = [] 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: new_object = self.model() form_validated = False prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(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]) request_files = request.FILES filter_params = { '%s__pk' % original_obj.__class__.__name__.lower(): original_obj.pk } inlined_objs = inline.model.objects.filter(**filter_params) for n, inlined_obj in enumerate(inlined_objs.all()): for field in inlined_obj._meta.fields: if isinstance( field, FileField) and field not in request_files: value = field.value_from_object(inlined_obj) file_field_name = '{}-{}-{}'.format( prefix, n, field.name) request_files.setdefault(file_field_name, value) formset = FormSet( data=request.POST, files=request_files, instance=new_object, save_as_new="_saveasnew" in request.POST, # ???? prefix=prefix) formsets.append(formset) if all_valid(formsets) and form_validated: # if original model has any file field, save new model # with same paths to these files for name in vars(original_obj): field = getattr(original_obj, name) if isinstance(field, FieldFile) and name not in request.FILES: setattr(new_object, name, field) self.save_model(request, new_object, form, False) self.save_related(request, form, formsets, False) try: self.log_addition(request, new_object) except TypeError: # In Django 1.9 we need one more param self.log_addition(request, new_object, "Cloned object") return self.response_add(request, new_object, None) else: initial = model_to_dict(original_obj) initial = self.tweak_cloned_fields(initial) form = ModelForm(initial=initial) prefixes = {} for FormSet, inline in self.get_formsets_with_inlines(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]) initial = [] queryset = inline.get_queryset(request).filter( **{FormSet.fk.name: original_obj}) for obj in queryset: initial.append( model_to_dict( obj, exclude=[obj._meta.pk.name, FormSet.fk.name])) initial = self.tweak_cloned_inline_fields(prefix, initial) formset = FormSet(prefix=prefix, initial=initial) # Since there is no way to customize the `extra` in the constructor, # construct the forms again... # most of this view is a hack, but this is the ugliest one formset.extra = len(initial) + formset.extra # _construct_forms() was removed on django 1.6 # see https://github.com/django/django/commit/ef79582e8630cb3c119caed52130c9671188addd if hasattr(formset, '_construct_forms'): formset._construct_forms() formsets.append(formset) admin_form = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.get_prepopulated_fields(request), self.get_readonly_fields(request), model_admin=self) media = self.media + admin_form.media inline_admin_formsets = [] for inline, formset in zip(self.get_inline_instances(request), formsets): fieldsets = list(inline.get_fieldsets(request, original_obj)) readonly = list(inline.get_readonly_fields(request, original_obj)) prepopulated = dict( inline.get_prepopulated_fields(request, original_obj)) inline_admin_formset = InlineAdminFormSetFakeOriginal( inline, formset, fieldsets, prepopulated, readonly, model_admin=self) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media title = u'{0} {1}'.format(self.clone_verbose_name, opts.verbose_name) context = { 'title': title, 'original': title, 'adminform': admin_form, 'is_popup': "_popup" in getattr(request, 'REQUEST', request.GET), 'show_delete': False, 'media': 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, form_url=form_url, change=False)
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='../add/') formsets = [] form = self.get_main_view_form(request, obj) if request.method == 'POST': if form.is_valid(): form_validated = True instance = self.save_form(request, form, change=True) else: form_validated = False instance = obj else: instance = obj for formset in self.get_formset_instances(request, instance, is_new=False): formsets.append(formset) if request.method == 'POST' and all_valid(formsets) and form_validated: self.save_view_formsets(request, instance, form, formsets, is_new=False) return self.response_change(request, instance) if hasattr(self, 'get_prepopulated_field'): # Django 1.4 prepopulated_fields = self.get_prepopulated_field(request) else: prepopulated_fields = self.prepopulated_fields adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), prepopulated_fields, self.get_readonly_fields(request, obj), model_admin=self) media = self.media + adminForm.media inline_admin_formsets = [] for inline_admin_formset in self.get_inline_admin_formsets(request, formsets, obj): inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media for nested in getattr(inline_admin_formset, 'inlines', []): media += nested.media context = { 'title': _('Change %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'is_popup': (IS_POPUP_VAR in request.POST or IS_POPUP_VAR in request.GET), 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': reverse('admin:index'), 'app_label': opts.app_label, } if hasattr(self, 'get_preserved_filters'): # Django 1.6 context['preserved_filters'] = self.get_preserved_filters(request) context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj, form_url=form_url)
def clone_view(self, request, object_id, form_url='', extra_context=None): opts = self.model._meta if not self.has_add_permission(request): raise PermissionDenied original_obj = self.get_object(request, unquote(object_id)) if original_obj is None: raise Http404(_('{name} object with primary key {key} does not exist.'.format( name=force_text(opts.verbose_name), key=repr(escape(object_id)) ))) ModelForm = self.get_form(request) formsets = [] # NOTE: Django 1.5 has a secong argument on get_inline_instances() inline_instances = self.get_inline_instances(request) 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: new_object = self.model() form_validated = False prefixes = {} for FormSet, inline in zip(self.get_formsets(request), inline_instances): 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) formsets.append(formset) if all_valid(formsets) and form_validated: # if original model has any file field, save new model # with same paths to these files for name in vars(original_obj): field = getattr(original_obj, name) if isinstance(field, FieldFile) and name not in request.FILES: setattr(new_object, name, field) self.save_model(request, new_object, form, False) self.save_related(request, form, formsets, False) self.log_addition(request, new_object) if VERSION[1] <= 4: # Until Django 1.4 giving %s in the url would be replaced with # object primary key. # I can't use the default because it goes back only one level # ('../%s/') and now we are under clone url, so we need one more level post_url_continue = '../../%s/' else: # Since 1.5 '%s' was deprecated and if None is given reverse() will # be used and do the right thing post_url_continue = None return self.response_add(request, new_object, post_url_continue) else: initial = model_to_dict(original_obj) initial = self.tweak_cloned_fields(initial) form = ModelForm(initial=initial) prefixes = {} for FormSet, inline in zip(self.get_formsets(request), inline_instances): 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]) initial = [] # Django 1.8 Patch if hasattr(inline, 'queryset'): get_queryset = inline.queryset else: get_queryset = inline.get_queryset queryset = get_queryset(request).filter( **{FormSet.fk.name: original_obj}) for obj in queryset: initial.append(model_to_dict(obj, exclude=[obj._meta.pk.name, FormSet.fk.name])) initial = self.tweak_cloned_inline_fields(prefix, initial) formset = FormSet(prefix=prefix, initial=initial) # Since there is no way to customize the `extra` in the constructor, # construct the forms again... # most of this view is a hack, but this is the ugliest one formset.extra = len(initial) + formset.extra # _construct_forms() was removed on django 1.6 # see https://github.com/django/django/commit/ef79582e8630cb3c119caed52130c9671188addd if hasattr(formset, '_construct_forms'): formset._construct_forms() formsets.append(formset) admin_form = helpers.AdminForm( form, list(self.get_fieldsets(request)), self.get_prepopulated_fields(request), self.get_readonly_fields(request), model_admin=self ) media = self.media + admin_form.media inline_admin_formsets = [] for inline, formset in zip(inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, original_obj)) readonly = list(inline.get_readonly_fields(request, original_obj)) prepopulated = dict(inline.get_prepopulated_fields(request, original_obj)) inline_admin_formset = InlineAdminFormSetFakeOriginal(inline, formset, fieldsets, prepopulated, readonly, model_admin=self) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media title = u'{0} {1}'.format(self.clone_verbose_name, opts.verbose_name) context = { 'title': title, 'original': title, 'adminform': admin_form, 'is_popup': "_popup" in request.REQUEST, 'show_delete': False, 'media': 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, form_url=form_url, change=False )
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('%s:%s_%s_add' % (self.admin_site.name, 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) 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), inline_instances): 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.queryset(request)) formsets.append(formset) if all_valid(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 zip(self.get_formsets(request, obj), inline_instances): 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.queryset(request)) formsets.append(formset) adminForm = helpers.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 = helpers.InlineAdminFormSet(inline, formset, fieldsets, prepopulated, readonly, model_admin=self) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media context = self.get_context_data(**{ 'title': _('Change %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'object_id': object_id, 'original': obj, 'is_popup': "_popup" in request.REQUEST, 'media': 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, 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 app_label = opts.app_label if not self.has_add_permission(request): raise PermissionDenied if self.has_change_permission(request, None): # redirect to list view post_url = '../' else: # Object list will give 'Permission Denied', so go back to admin home post_url = '../../../' ModelForm = self.get_form(request) formsets = [] if request.method == 'POST': form = ModelForm(request.POST, request.FILES) if form.is_valid(): form_validated = True new_object = self.save_form(request, form, change=False) else: form_validated = False new_object = self.model() for FormSet in self.get_formsets(request): formset = FormSet( data=request.POST, files=request.FILES, instance=new_object, save_as_new=request.POST.has_key("_saveasnew")) formsets.append(formset) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, change=False) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=False) self.log_addition(request, new_object) return self.response_add(request, new_object) else: form = ModelForm(initial=dict(request.GET.items())) for FormSet in self.get_formsets(request): formset = FormSet(instance=self.model()) formsets.append(formset) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request)) inline_admin_formset = helpers.InlineAdminFormSet( inline, formset, fieldsets) inline_admin_formsets.append(inline_admin_formset) media = media + inline_admin_formset.media context = { 'title': _('Add %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'is_popup': request.REQUEST.has_key('_popup'), 'show_delete': False, 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': self.admin_site.root_path, 'app_label': app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, add=True)
def change_view(self, request, object_id, extra_context=None): "The 'change' admin view for this model." model = self.model opts = model._meta app_label = opts.app_label try: obj = model._default_manager.get(pk=object_id) except model.DoesNotExist: # Don't raise Http404 just yet, because we haven't checked # permissions yet. We don't want an unauthenticated user to be able # to determine whether a given object exists. obj = None if not self.has_change_permission(request, obj): raise PermissionDenied if obj is None: raise Http404( '%s object with primary key %r does not exist.' % (force_unicode(opts.verbose_name), escape(object_id))) if request.POST and request.POST.has_key("_saveasnew"): 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 for FormSet in self.get_formsets(request, new_object): formset = FormSet(request.POST, request.FILES, instance=new_object) formsets.append(formset) 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) for FormSet in self.get_formsets(request, obj): formset = FormSet(instance=obj) formsets.append(formset) adminForm = helpers.AdminForm(form, self.get_fieldsets(request, obj), self.prepopulated_fields) media = self.media + adminForm.media inline_admin_formsets = [] for inline, formset in zip(self.inline_instances, formsets): fieldsets = list(inline.get_fieldsets(request, obj)) inline_admin_formset = helpers.InlineAdminFormSet( inline, formset, fieldsets) 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': request.REQUEST.has_key('_popup'), 'media': mark_safe(media), 'inline_admin_formsets': inline_admin_formsets, 'errors': helpers.AdminErrorList(form, formsets), 'root_path': self.admin_site.root_path, 'app_label': app_label, } context.update(extra_context or {}) return self.render_change_form(request, context, change=True, obj=obj)
def changeform_view(self, request, object_id=None, form_url='', extra_context=None): """ This follows closely the base implementation from Django 1.7's django.contrib.admin.options.ModelAdmin with the explicitly marked modifications. """ to_field = request.POST.get(TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)) if to_field and not self.to_field_allowed(request, to_field): raise DisallowedModelAdminToField( "The field %s cannot be referenced." % to_field) model = self.model opts = model._meta add = object_id is None if add: if not self.has_add_permission(request): raise PermissionDenied obj = None else: 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_text(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.model_name), current_app=self.admin_site.name)) #### begin modification #### # make sure that the user has a full session length time for the current # edit activity request.session.set_expiry(settings.SESSION_COOKIE_AGE) #### end modification #### ModelForm = self.get_form(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=not add) else: form_validated = False new_object = form.instance formsets, inline_instances = self._create_formsets(request, new_object, change=not add) if all_valid(formsets) and form_validated: self.save_model(request, new_object, form, not add) self.save_related(request, form, formsets, not add) if add: self.log_addition(request, new_object) return self.response_add(request, new_object) else: 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: if add: initial = self.get_changeform_initial_data(request) form = ModelForm(initial=initial) formsets, inline_instances = self._create_formsets( request, self.model(), change=False) else: form = ModelForm(instance=obj) formsets, inline_instances = self._create_formsets(request, obj, change=True) adminForm = helpers.AdminForm(form, list(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_formsets = self.get_inline_formsets(request, formsets, inline_instances, obj) for inline_formset in inline_formsets: media = media + inline_formset.media context = dict(self.admin_site.each_context(), title=(_('Add %s') if add else _('Change %s')) % force_text(opts.verbose_name), adminform=adminForm, object_id=object_id, original=obj, is_popup=(IS_POPUP_VAR in request.REQUEST or \ IS_POPUP_O2M_VAR in request.REQUEST), to_field=to_field, media=media, inline_admin_formsets=inline_formsets, errors=helpers.AdminErrorList(form, formsets), preserved_filters=self.get_preserved_filters(request), kb_link=settings.KNOWLEDGE_BASE_URL, app_label=opts.app_label, show_delete=False, ) context.update(extra_context or {}) return self.render_change_form(request, context, add=add, change=not add, 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 = [] 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 zip(self.get_formsets(request), self.get_inline_instances(request)): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: 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.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 = "%s-%s" % (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=False) form.save_m2m() for formset in formsets: self.save_formset(request, form, formset, change=False) self.log_addition(request, new_object) 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 zip(self.get_formsets(request), self.get_inline_instances(request)): prefix = FormSet.get_default_prefix() prefixes[prefix] = prefixes.get(prefix, 0) + 1 if prefixes[prefix] != 1: prefix = "%s-%s" % (prefix, prefixes[prefix]) formset = FormSet(instance=self.model(), prefix=prefix, queryset=inline.queryset(request)) formsets.append(formset) adminForm = helpers.AdminForm(form, list(self.get_fieldsets(request)), self.prepopulated_fields, self.get_readonly_fields(request), 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)) readonly = list(inline.get_readonly_fields(request)) 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': _('Add %s') % force_unicode(opts.verbose_name), 'adminform': adminForm, 'is_popup': "_popup" in request.REQUEST, 'show_delete': False, '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, form_url=form_url, add=True)
def validate_inlines(self, inlines): inlines_validated = all_valid(inlines) return inlines, inlines_validated