def vcp_home(request): aux_enable_https = models.VcenterAuxSettings.objects.latest('id') obj = models.VcenterConfiguration.objects.latest('id') if request.method == 'POST': form = VcenterConfigurationForm(request.POST, instance=obj) if form.is_valid(): form.vcp_action = 'INSTALL' try: form.save() return JsonResp( request, message=_("The plugin has been successfully installed"), ) except CallTimeout: return JsonResp( request, message=_( "The plugin could not be installed because of timeout." " Most probably the port provided was incorrect"), ) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form) else: form = VcenterConfigurationForm(instance=obj) if obj.vc_installed: form.fields['vc_ip'].widget.attrs['readonly'] = True return render(request, "vcp/index.html", { 'form': form, 'aux_enable_https': aux_enable_https, })
def services_cifs(request): try: cifs = models.CIFS.objects.all()[0] except Exception: cifs = models.CIFS() try: it = idmap_tdb.objects.get( idmap_ds_type=DS_TYPE_CIFS, idmap_ds_id=cifs.id ) except Exception: it = idmap_tdb() if request.method == "POST": form = CIFSForm(request.POST, instance=cifs) try: if form.is_valid(): form.save() else: return JsonResp(request, form=form) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form) except ServiceFailed as e: return JsonResp( request, form=form, error=True, message=e.value, events=["serviceFailed(\"%s\")" % e.service]) except MiddlewareError as e: return JsonResp( request, form=form, error=True, message=_("Error: %s") % str(e)) idmap_form = idmap_tdb_Form(request.POST, instance=it) if idmap_form.is_valid(): idmap_form.save() return JsonResp( request, message=_("SMB successfully updated.") ) else: return JsonResp(request, form=idmap_form) else: form = CIFSForm(instance=cifs) idmap_form = idmap_tdb_Form(instance=it) idmap_form.fields['idmap_tdb_range_low'].label = _("Idmap Range Low") idmap_form.fields['idmap_tdb_range_high'].label = _("Idmap Range High") return render(request, 'services/cifs.html', { 'form': form, 'idmap_form': idmap_form })
def vcp_vcenterauxsettings(request): vcpaux = models.VcenterAuxSettings.objects.latest('id') if request.method == "POST": form = VcenterAuxSettingsForm(request.POST, instance=vcpaux) if form.is_valid(): try: form.save() events = [] form.done(request, events) return JsonResp( request, message=_( "vCenter Auxiliary Settings successfully edited."), events=events, ) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form) else: form = VcenterAuxSettingsForm(instance=vcpaux) return render(request, 'vcp/aux_settings.html', {'form': form})
def vcp_uninstall(request): obj = models.VcenterConfiguration.objects.latest('id') if request.method == 'POST': form = VcenterConfigurationForm(request.POST, instance=obj) if form.is_valid(): form.vcp_action = 'UNINSTALL' try: form.save() # TODO: THE UI DISPLAYS OLD CREDENTIALS AFTER UN-INSTALLATION, THAT NEEDS BE CHANGED return JsonResp( request, message=_("The plugin has been successfully uninstalled"), ) except CallTimeout: return JsonResp( request, message=_( "The plugin could not be installed because of timeout." " Most probably the port provided was incorrect"), ) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form)
def services_s3(request): try: s3 = models.S3.objects.all()[0] except Exception: s3 = models.S3() if request.method == "POST": form = S3Form(request.POST, instance=s3) if form.is_valid(): try: form.save() return JsonResp(request, message=_("S3 successfully edited.")) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form) else: return JsonResp(request, form=form) else: form = S3Form(instance=s3) s3_ui_url = "http://%s:%s" % (s3.s3_bindip, s3.s3_bindport) if s3.s3_bindip == "0.0.0.0": s3_ui_url = "http://%s:%s" % (request.META['HTTP_HOST'].split(':')[0], s3.s3_bindport) s3_started = notifier().started("s3") and s3.s3_browser return render(request, 'services/s3.html', { 'form': form, 's3': s3, 's3_ui_url': s3_ui_url, 's3_started': s3_started })
def vcp_upgrade(request): obj = models.VcenterConfiguration.objects.latest('id') if request.method == 'POST': form = VcenterConfigurationForm(request.POST, instance=obj) if form.is_valid(): if not form.is_update_needed(): return JsonResp( request, error=True, message=_("There are No updates available at this time.")) else: form.vcp_action = 'UPGRADE' try: form.save() return JsonResp( request, message=_("The plugin has been successfully upgraded"), ) except CallTimeout: return JsonResp( request, message=_( "The plugin could not be installed because of timeout." " Most probably the port provided was incorrect"), ) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form)
def services_cifs(request): try: cifs = models.CIFS.objects.all()[0] except Exception: cifs = models.CIFS() try: it = idmap_tdb.objects.get( idmap_tdb_domain='DS_TYPE_DEFAULT_DOMAIN' ) except Exception: it = idmap_tdb() if request.method == "POST": form = CIFSForm(request.POST, instance=cifs) try: if form.is_valid(): form.save() else: return JsonResp(request, form=form) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form) except ServiceFailed as e: return JsonResp( request, form=form, error=True, message=e.value, events=["serviceFailed(\"%s\")" % e.service]) except MiddlewareError as e: return JsonResp( request, form=form, error=True, message=_("Error: %s") % str(e)) idmap_form = idmap_tdb_Form(request.POST, instance=it) if idmap_form.is_valid(): idmap_form.save() return JsonResp( request, message=_("SMB successfully updated.") ) else: return JsonResp(request, form=idmap_form) else: form = CIFSForm(instance=cifs) idmap_form = idmap_tdb_Form(instance=it) idmap_form.fields['idmap_tdb_range_low'].label = _("Idmap Range Low") idmap_form.fields['idmap_tdb_range_high'].label = _("Idmap Range High") return render(request, 'services/cifs.html', { 'form': form, 'idmap_form': idmap_form })
def volume_lock(request, object_id): volume = models.Volume.objects.get(id=object_id) assert (volume.vol_encrypt > 0) if request.method == "POST": _n = notifier() if '__confirm' not in request.POST and not _n.is_freenas( ) and _n.failover_licensed(): remaining_volumes = [ v for v in models.Volume.objects.exclude(pk=object_id) if v.is_decrypted() ] if not remaining_volumes: message = render_to_string( 'freeadmin/generic_model_confirm.html', { 'message': 'Warning: Locking this volume will prevent failover from functioning correctly.<br />Do you want to continue?', }) return JsonResp(request, confirm=message) form = forms.LockPassphraseForm(request.POST) if form.is_valid(): try: form.done(volume) except ValidationErrors as e: handle_middleware_validation(form, e) else: return JsonResp(request, message=_("Volume locked")) """ if hasattr(notifier, 'failover_status') and notifier().failover_status() == 'MASTER': from freenasUI.failover.enc_helper import LocalEscrowCtl escrowctl = LocalEscrowCtl() escrowctl.clear() try: os.unlink('/tmp/.failover_master') except Exception: pass try: with client as c: c.call('failover.call_remote', 'failover.encryption_clearkey') except Exception: log.warn('Failed to clear key on standby node, is it down?', exc_info=True) """ return JsonResp(request, form=form) else: form = forms.LockPassphraseForm() return render(request, "storage/lock.html", { 'form': form, })
def services_cifs(request): try: cifs = models.CIFS.objects.all()[0] except Exception: cifs = models.CIFS() try: it = idmap_tdb.objects.get( idmap_ds_type=DS_TYPE_CIFS, idmap_ds_id=cifs.id ) except Exception: it = idmap_tdb() if request.method == "POST": try: form = CIFSForm(request.POST, instance=cifs) if form.is_valid(): form.save() else: return JsonResp(request, form=form) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form) idmap_form = idmap_tdb_Form(request.POST, instance=it) if idmap_form.is_valid(): idmap_form.save() return JsonResp( request, message=_("SMB successfully updated.") ) else: return JsonResp(request, form=idmap_form) else: form = CIFSForm(instance=cifs) idmap_form = idmap_tdb_Form(instance=it) idmap_form.fields['idmap_tdb_range_low'].label = _("Idmap Range Low") idmap_form.fields['idmap_tdb_range_high'].label = _("Idmap Range High") return render(request, 'services/cifs.html', { 'form': form, 'idmap_form': idmap_form })
def volume_lock(request, object_id): volume = models.Volume.objects.get(id=object_id) assert(volume.vol_encrypt > 0) if request.method == "POST": _n = notifier() if '__confirm' not in request.POST and not _n.is_freenas() and _n.failover_licensed(): remaining_volumes = [v for v in models.Volume.objects.exclude(pk=object_id) if v.is_decrypted()] if not remaining_volumes: message = render_to_string('freeadmin/generic_model_confirm.html', { 'message': 'Warning: Locking this volume will prevent failover from functioning correctly.<br />Do you want to continue?', }) return JsonResp(request, confirm=message) form = forms.LockPassphraseForm(request.POST) if form.is_valid(): try: form.done(volume) except ValidationErrors as e: handle_middleware_validation(form, e) else: return JsonResp(request, message=_("Volume locked")) """ if hasattr(notifier, 'failover_status') and notifier().failover_status() == 'MASTER': from freenasUI.failover.enc_helper import LocalEscrowCtl escrowctl = LocalEscrowCtl() escrowctl.clear() try: os.unlink('/tmp/.failover_master') except Exception: pass try: with client as c: c.call('failover.call_remote', 'failover.encryption_clearkey') except Exception: log.warn('Failed to clear key on standby node, is it down?', exc_info=True) """ return JsonResp(request, form=form) else: form = forms.LockPassphraseForm() return render(request, "storage/lock.html", { 'form': form, })
def add(request): if request.method == 'POST': uuid = request.GET.get('uuid') if uuid: with client as c: jobs = c.call('core.get_jobs', [('id', '=', int(uuid))]) if jobs: job = jobs[0] if job['state'] in ('FAILED', 'ABORTED'): initial = request.session.get('vm_add') or {} form = forms.VMForm(initial) form.is_valid() form._errors['__all__'] = form.error_class( [f'Error creating VM: {job.get("error")}']) return render(request, 'vm/vm_add.html', { 'form': form, }) elif job['state'] == 'SUCCESS': return JsonResp( request, message=_('VM has been successfully created.'), ) return HttpResponse(uuid, status=202) form = forms.VMForm(request.POST) if form.is_valid(): try: obj = form.save() except ValidationErrors as e: handle_middleware_validation(form, e) else: if isinstance(obj, int): request.session['vm_add'] = request.POST.copy() request.session['vm_add_job'] = obj return HttpResponse(obj, status=202) return JsonResp(request, message=_('VM has been successfully created.')) return JsonResp(request, form=form) else: request.session['vm_add_job'] = None form = forms.VMForm() return render(request, 'vm/vm_add.html', { 'form': form, })
def add(request): if request.method == 'POST': uuid = request.GET.get('uuid') if uuid: with client as c: jobs = c.call('core.get_jobs', [('id', '=', int(uuid))]) if jobs: job = jobs[0] if job['state'] in ('FAILED', 'ABORTED'): initial = request.session.get('vm_add') or {} form = forms.VMForm(initial) form.is_valid() form._errors['__all__'] = form.error_class([f'Error creating VM: {job.get("error")}']) return render(request, 'vm/vm_add.html', { 'form': form, }) elif job['state'] == 'SUCCESS': return JsonResp( request, message=_('VM has been successfully created.'), ) return HttpResponse(uuid, status=202) form = forms.VMForm(request.POST) if form.is_valid(): try: obj = form.save() except ValidationErrors as e: handle_middleware_validation(form, e) else: if isinstance(obj, int): request.session['vm_add'] = request.POST.copy() request.session['vm_add_job'] = obj return HttpResponse(obj, status=202) return JsonResp(request, message=_('VM has been successfully created.')) return JsonResp(request, form=form) else: request.session['vm_add_job'] = None form = forms.VMForm() return render(request, 'vm/vm_add.html', { 'form': form, })
def services_s3(request): try: s3 = models.S3.objects.all()[0] except Exception: s3 = models.S3() if request.method == "POST": form = S3Form(request.POST, instance=s3) if form.is_valid(): try: form.save() return JsonResp( request, message=_("S3 successfully edited.") ) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form) else: return JsonResp(request, form=form) else: form = S3Form(instance=s3) s3_ui_url = "http://%s:%s" % (s3.s3_bindip, s3.s3_bindport) if s3.s3_bindip == "0.0.0.0": s3_ui_url = "http://%s:%s" % (request.META['HTTP_HOST'].split(':')[0], s3.s3_bindport) s3_started = notifier().started("s3") and s3.s3_browser return render(request, 'services/s3.html', { 'form': form, 's3': s3, 's3_ui_url': s3_ui_url, 's3_started': s3_started })
def vcp_repair(request): obj = models.VcenterConfiguration.objects.latest('id') if request.method == 'POST': form = VcenterConfigurationForm(request.POST, instance=obj) if form.is_valid(): form.vcp_action = 'REPAIR' try: form.save() return JsonResp( request, message=_("The plugin has been successfully installed"), ) except CallTimeout: return JsonResp( request, message=_( "The plugin could not be installed because of timeout." " Most probably the port provided was incorrect"), ) except ValidationErrors as e: handle_middleware_validation(form, e) return JsonResp(request, form=form)
def save(self, bundle, skip_errors=False): # Check if they're authorized. if bundle.obj.pk: self.authorized_update_detail(self.get_object_list(bundle.request), bundle) else: self.authorized_create_detail(self.get_object_list(bundle.request), bundle) # Remove all "private" attributes data = dict(bundle.obj.__dict__) for key, val in list(data.items()): if key.startswith('_'): del data[key] continue # Add the pk of the foreign key in the mix if key.endswith('_id'): noid = key[:-3] field = getattr(bundle.obj.__class__, noid, None) if not field: continue if field and isinstance(field.field, ForeignKey): data[noid] = val del data[key] else: try: bundle.obj.__class__._meta.get_field(key) except FieldDoesNotExist: del data[key] data.update(bundle.data) bundle.data = data """ Get rid of None values, it means they were not passed to the API and will fail serialization """ querydict = data.copy() for key, val in list(querydict.items()): if val is None: del querydict[key] querydict = QueryDict(urllib.parse.urlencode(querydict, doseq=True)) # Allow one form validation for each method method_validation = '%s_validation' % bundle.request.method.lower() validation = getattr(self._meta, method_validation, self._meta.validation) form = validation.form_class( querydict, instance=bundle.obj, api_validation=True, ) if not self.is_form_valid(bundle, form): raise ImmediateHttpResponse(response=self.error_response( bundle.request, bundle.errors, response_class=http.HttpConflict, )) """ FIXME Saving the objects under a transaction won't work very well because some rc.d scripts and rc.conf will not be able to visualize the changes until the transaction is committed. # with transaction.atomic(): """ try: form.save() if form._errors: # This might happen for a form which does not raise validation errors for django compatibility raise ValidationErrors([]) except ValidationErrors as e: handle_middleware_validation(form, e) raise ImmediateHttpResponse(response=self.error_response( bundle.request, form._errors, response_class=http.HttpConflict, )) self.post_form_save_hook(bundle, form) bundle.obj = form.instance bundle.objects_saved.add(self.create_identifier(bundle.obj)) # Now pick up the M2M bits. m2m_bundle = self.hydrate_m2m(bundle) self.save_m2m(m2m_bundle) if hasattr(form, 'done') and callable(form.done): form.done(request=bundle.request, events=[]) return bundle
def edit(self, request, oid, mf=None): from freenasUI.freeadmin.navtree import navtree from freenasUI.freeadmin.views import JsonResp m = self._model if 'inline' in request.GET: inline = True else: inline = False context = { 'app': m._meta.app_label, 'model': m, 'modeladmin': m._admin, 'mf': mf, 'oid': oid, 'inline': inline, 'extra_js': m._admin.extra_js, 'model_name': m._meta.model_name, 'verbose_name': m._meta.verbose_name, 'deletable': m._admin.deletable, } if 'deletable' in request.GET: context.update({'deletable': False}) instance = get_object_or_404(m, pk=oid) if not isinstance(navtree._modelforms[m], dict): mf = navtree._modelforms[m] else: if mf is None: try: mf = navtree._modelforms[m][m.FreeAdmin.edit_modelform] except: mf = list(navtree._modelforms[m].values())[-1] else: mf = navtree._modelforms[m][mf] formsets = {} if request.method == "POST": mf = mf(request.POST, request.FILES, instance=instance) if m._admin.advanced_fields: mf.advanced_fields.extend(m._admin.advanced_fields) valid = True if m._admin.inlines: for inlineopts in m._admin.inlines: inline = inlineopts.get("form") prefix = inlineopts.get("prefix") formset = inlineopts.get("formset") _temp = __import__( '%s.forms' % m._meta.app_label, globals(), locals(), [inline], 0) inline = getattr(_temp, inline) if formset: formset = getattr(_temp, formset) else: formset = FreeBaseInlineFormSet extrakw = { 'can_delete': True, } fset_fac = inlineformset_factory( m, inline._meta.model, form=inline, formset=formset, extra=0, **extrakw) try: fsname = 'formset_%s' % ( inline._meta.model._meta.model_name, ) fset = fset_fac( request.POST, prefix=prefix, parent=mf, instance=instance) if not fset.show_condition(): continue formsets[fsname] = { 'instance': fset, 'position': inlineopts.get('position', 'bottom'), } except dforms.ValidationError: pass for name, fsinfo in list(formsets.items()): for frm in fsinfo['instance'].forms: valid &= frm.is_valid() valid &= fsinfo['instance'].is_valid() valid &= mf.is_valid(formsets=formsets) if valid: if '__confirm' not in request.POST: message = self.get_confirm_message( 'edit', obj=instance, form=mf, ) if message: return JsonResp( request, confirm=self.confirm(message), ) try: mf.save() if not isinstance(mf, MiddlewareModelForm): for name, fsinfo in list(formsets.items()): fsinfo['instance'].save() events = [] if hasattr(mf, "done") and callable(mf.done): mf.done(request=request, events=events) if 'iframe' in request.GET: return JsonResp( request, form=mf, formsets=formsets, message=_("%s successfully updated.") % ( m._meta.verbose_name, )) else: return JsonResp( request, form=mf, formsets=formsets, message=_("%s successfully updated.") % ( m._meta.verbose_name, ), events=events) except ValidationErrors as e: handle_middleware_validation(mf, e) return JsonResp(request, form=mf, formsets=formsets) except ServiceFailed as e: return JsonResp( request, form=mf, error=True, message=e.value, events=["serviceFailed(\"%s\")" % e.service]) except MiddlewareError as e: return JsonResp( request, form=mf, error=True, message=_("Error: %s") % str(e)) else: return JsonResp(request, form=mf, formsets=formsets) else: mf = mf(instance=instance) if m._admin.advanced_fields: mf.advanced_fields.extend(m._admin.advanced_fields) if m._admin.inlines: extrakw = { 'can_delete': True, } for inlineopts in m._admin.inlines: inline = inlineopts.get("form") prefix = inlineopts.get("prefix") formset = inlineopts.get("formset") _temp = __import__( '%s.forms' % m._meta.app_label, globals(), locals(), [inline], 0) inline = getattr(_temp, inline) if formset: formset = getattr(_temp, formset) else: formset = FreeBaseInlineFormSet """ Do not add any extra empty form for the inline formset in case there is already any item in the relationship """ extra = 1 fk_name = None for field in inline._meta.model._meta.fields: if isinstance(field, ForeignKey) and m is field.rel.to: fk_name = field.name break if fk_name: qs = inline._meta.model.objects.filter( **{'%s__id' % fk_name: instance.pk} ) if qs.count() > 0: extra = 0 fset_fac = inlineformset_factory( m, inline._meta.model, form=inline, formset=formset, extra=extra, **extrakw) fsname = 'formset_%s' % ( inline._meta.model._meta.model_name, ) fset = fset_fac( prefix=prefix, instance=instance, parent=mf, ) if not fset.show_condition(): continue fset.verbose_name = ( inline._meta.model._meta.verbose_name ) formsets[fsname] = { 'instance': fset, 'position': inlineopts.get('position', 'bottom'), } context.update({ 'form': mf, 'formsets': formsets, 'instance': instance, 'delete_url': reverse('freeadmin_%s_%s_delete' % ( m._meta.app_label, m._meta.model_name, ), kwargs={ 'oid': instance.pk, }), 'hook_buttons': appPool.hook_form_buttons( str(type(mf).__name__), mf, 'edit', ), }) context.update(self.get_extra_context('edit', request=request, form=mf)) template = "%s/%s_edit.html" % ( m._meta.app_label, m._meta.object_name.lower(), ) try: get_template(template) except TemplateDoesNotExist: template = 'freeadmin/generic_model_edit.html' if 'iframe' in request.GET: resp = render( request, template, context, content_type='text/html') resp.content = ( "<html><body><textarea>" + resp.content + "</textarea></boby></html>") return resp else: return render( request, template, context, content_type='text/html')
def add(self, request, mf=None): """ Magic happens here We dynamically import the module based on app and model names passed as view argument From there we retrieve the ModelForm associated (which was discovered previously on the auto_generate process) """ from freenasUI.freeadmin.navtree import navtree from freenasUI.freeadmin.views import JsonResp m = self._model app = self._model._meta.app_label context = { 'app': app, 'model': m, 'modeladmin': m._admin, 'mf': mf, 'model_name': m._meta.model_name, 'verbose_name': m._meta.verbose_name, 'extra_js': m._admin.extra_js, } if not isinstance(navtree._modelforms[m], dict): mf = navtree._modelforms[m] else: if mf is None: try: mf = navtree._modelforms[m][m._admin.create_modelform] except: try: mf = navtree._modelforms[m][m._admin.edit_modelform] except: mf = list(navtree._modelforms[m].values())[-1] else: mf = navtree._modelforms[m][mf] instance = m() formsets = {} if request.method == "POST": mf = mf(request.POST, request.FILES, instance=instance) if m._admin.advanced_fields: mf.advanced_fields.extend(m._admin.advanced_fields) valid = True if m._admin.inlines: for inlineopts in m._admin.inlines: inline = inlineopts.get("form") prefix = inlineopts.get("prefix") formset = inlineopts.get("formset") _temp = __import__( '%s.forms' % app, globals(), locals(), [inline], 0) inline = getattr(_temp, inline) if formset: formset = getattr(_temp, formset) else: formset = FreeBaseInlineFormSet extrakw = { 'can_delete': False } fset_fac = inlineformset_factory( m, inline._meta.model, form=inline, formset=formset, extra=0, **extrakw) try: fsname = 'formset_%s' % ( inline._meta.model._meta.model_name, ) fset = fset_fac( request.POST, prefix=prefix, parent=mf, instance=instance) if not fset.show_condition(): continue formsets[fsname] = { 'instance': fset, 'position': inlineopts.get('position', 'bottom') } except dforms.ValidationError: pass for name, fsinfo in list(formsets.items()): for frm in fsinfo['instance'].forms: valid &= frm.is_valid() valid &= fsinfo['instance'].is_valid() valid &= mf.is_valid(formsets=formsets) if valid: if '__confirm' not in request.POST: message = self.get_confirm_message( 'add', obj=instance, form=mf, ) if message: return JsonResp( request, confirm=self.confirm(message), ) try: mf.save() if not isinstance(mf, MiddlewareModelForm): for name, fsinfo in list(formsets.items()): fsinfo['instance'].save() events = [] if hasattr(mf, "done") and callable(mf.done): mf.done(request=request, events=events) return JsonResp( request, form=mf, formsets=formsets, message=_("%s successfully updated.") % ( m._meta.verbose_name, ), events=events) except ValidationErrors as e: handle_middleware_validation(mf, e) return JsonResp(request, form=mf, formsets=formsets) except ServiceFailed as e: return JsonResp( request, error=True, message=e.value, events=["serviceFailed(\"%s\")" % e.service]) except MiddlewareError as e: return JsonResp( request, error=True, message=_("Error: %s") % str(e)) else: return JsonResp(request, form=mf, formsets=formsets) else: mf = mf() if m._admin.advanced_fields: mf.advanced_fields.extend(m._admin.advanced_fields) if m._admin.inlines: extrakw = { 'can_delete': False } for inlineopts in m._admin.inlines: inline = inlineopts.get("form") prefix = inlineopts.get("prefix") formset = inlineopts.get("formset") _temp = __import__( '%s.forms' % app, globals(), locals(), [inline], 0) inline = getattr(_temp, inline) if formset: formset = getattr(_temp, formset) else: formset = FreeBaseInlineFormSet fset_fac = inlineformset_factory( m, inline._meta.model, form=inline, formset=formset, extra=1, **extrakw) fsname = 'formset_%s' % ( inline._meta.model._meta.model_name, ) fset = fset_fac( prefix=prefix, instance=instance, parent=mf ) if not fset.show_condition(): continue fset.verbose_name = ( inline._meta.model._meta.verbose_name ) formsets[fsname] = { 'instance': fset, 'position': inlineopts.get('position', 'bottom'), } context.update({ 'form': mf, 'formsets': formsets, }) context.update(self.get_extra_context('add', request=request, form=mf)) template = "%s/%s_add.html" % ( m._meta.app_label, m._meta.object_name.lower(), ) try: get_template(template) except TemplateDoesNotExist: template = 'freeadmin/generic_model_add.html' return render(request, template, context)
def edit(self, request, oid, mf=None): from freenasUI.freeadmin.navtree import navtree from freenasUI.freeadmin.views import JsonResp m = self._model if 'inline' in request.GET: inline = True else: inline = False context = { 'app': m._meta.app_label, 'model': m, 'modeladmin': m._admin, 'mf': mf, 'oid': oid, 'inline': inline, 'extra_js': m._admin.extra_js, 'model_name': m._meta.model_name, 'verbose_name': m._meta.verbose_name, 'deletable': m._admin.deletable, } if 'deletable' in request.GET: context.update({'deletable': False}) instance = get_object_or_404(m, pk=oid) if not isinstance(navtree._modelforms[m], dict): mf = navtree._modelforms[m] else: if mf is None: try: mf = navtree._modelforms[m][m.FreeAdmin.edit_modelform] except: mf = list(navtree._modelforms[m].values())[-1] else: mf = navtree._modelforms[m][mf] formsets = {} if request.method == "POST": mf = mf(request.POST, request.FILES, instance=instance) if m._admin.advanced_fields: mf.advanced_fields.extend(m._admin.advanced_fields) valid = True if m._admin.inlines: for inlineopts in m._admin.inlines: inline = inlineopts.get("form") prefix = inlineopts.get("prefix") formset = inlineopts.get("formset") _temp = __import__('%s.forms' % m._meta.app_label, globals(), locals(), [inline], 0) inline = getattr(_temp, inline) if formset: formset = getattr(_temp, formset) else: formset = FreeBaseInlineFormSet extrakw = { 'can_delete': True, } fset_fac = inlineformset_factory(m, inline._meta.model, form=inline, formset=formset, extra=0, **extrakw) try: fsname = 'formset_%s' % ( inline._meta.model._meta.model_name, ) fset = fset_fac(request.POST, prefix=prefix, parent=mf, instance=instance) formsets[fsname] = { 'instance': fset, 'position': inlineopts.get('position', 'bottom'), } except dforms.ValidationError: pass for name, fsinfo in list(formsets.items()): for frm in fsinfo['instance'].forms: valid &= frm.is_valid() valid &= fsinfo['instance'].is_valid() valid &= mf.is_valid(formsets=formsets) if valid: if '__confirm' not in request.POST: message = self.get_confirm_message( 'edit', obj=instance, form=mf, ) if message: return JsonResp( request, confirm=self.confirm(message), ) try: mf.save() if not isinstance(mf, MiddlewareModelForm): for name, fsinfo in list(formsets.items()): fsinfo['instance'].save() events = [] if hasattr(mf, "done") and callable(mf.done): mf.done(request=request, events=events) if 'iframe' in request.GET: return JsonResp(request, form=mf, formsets=formsets, message=_("%s successfully updated.") % (m._meta.verbose_name, )) else: return JsonResp(request, form=mf, formsets=formsets, message=_("%s successfully updated.") % (m._meta.verbose_name, ), events=events) except ValidationErrors as e: handle_middleware_validation(mf, e) return JsonResp(request, form=mf, formsets=formsets) except ServiceFailed as e: return JsonResp( request, form=mf, error=True, message=e.value, events=["serviceFailed(\"%s\")" % e.service]) except MiddlewareError as e: return JsonResp(request, form=mf, error=True, message=_("Error: %s") % str(e)) else: return JsonResp(request, form=mf, formsets=formsets) else: mf = mf(instance=instance) if m._admin.advanced_fields: mf.advanced_fields.extend(m._admin.advanced_fields) if m._admin.inlines: extrakw = { 'can_delete': True, } for inlineopts in m._admin.inlines: inline = inlineopts.get("form") prefix = inlineopts.get("prefix") formset = inlineopts.get("formset") _temp = __import__('%s.forms' % m._meta.app_label, globals(), locals(), [inline], 0) inline = getattr(_temp, inline) if formset: formset = getattr(_temp, formset) else: formset = FreeBaseInlineFormSet """ Do not add any extra empty form for the inline formset in case there is already any item in the relationship """ extra = 1 fk_name = None for field in inline._meta.model._meta.fields: if isinstance(field, ForeignKey) and m is field.rel.to: fk_name = field.name break if fk_name: qs = inline._meta.model.objects.filter( **{'%s__id' % fk_name: instance.pk}) if qs.count() > 0: extra = 0 fset_fac = inlineformset_factory(m, inline._meta.model, form=inline, formset=formset, extra=extra, **extrakw) fsname = 'formset_%s' % ( inline._meta.model._meta.model_name, ) fset = fset_fac( prefix=prefix, instance=instance, parent=mf, ) fset.verbose_name = (inline._meta.model._meta.verbose_name) formsets[fsname] = { 'instance': fset, 'position': inlineopts.get('position', 'bottom'), } context.update({ 'form': mf, 'formsets': formsets, 'instance': instance, 'delete_url': reverse('freeadmin_%s_%s_delete' % ( m._meta.app_label, m._meta.model_name, ), kwargs={ 'oid': instance.pk, }), 'hook_buttons': appPool.hook_form_buttons( str(type(mf).__name__), mf, 'edit', ), }) context.update(self.get_extra_context('edit', request=request, form=mf)) template = "%s/%s_edit.html" % ( m._meta.app_label, m._meta.object_name.lower(), ) try: get_template(template) except TemplateDoesNotExist: template = 'freeadmin/generic_model_edit.html' if 'iframe' in request.GET: resp = render(request, template, context, content_type='text/html') resp.content = ("<html><body><textarea>" + resp.content + "</textarea></boby></html>") return resp else: return render(request, template, context, content_type='text/html')
def add(self, request, mf=None): """ Magic happens here We dynamically import the module based on app and model names passed as view argument From there we retrieve the ModelForm associated (which was discovered previously on the auto_generate process) """ from freenasUI.freeadmin.navtree import navtree from freenasUI.freeadmin.views import JsonResp m = self._model app = self._model._meta.app_label context = { 'app': app, 'model': m, 'modeladmin': m._admin, 'mf': mf, 'model_name': m._meta.model_name, 'verbose_name': m._meta.verbose_name, 'extra_js': m._admin.extra_js, } if not isinstance(navtree._modelforms[m], dict): mf = navtree._modelforms[m] else: if mf is None: try: mf = navtree._modelforms[m][m._admin.create_modelform] except: try: mf = navtree._modelforms[m][m._admin.edit_modelform] except: mf = list(navtree._modelforms[m].values())[-1] else: mf = navtree._modelforms[m][mf] instance = m() formsets = {} if request.method == "POST": mf = mf(request.POST, request.FILES, instance=instance) if m._admin.advanced_fields: mf.advanced_fields.extend(m._admin.advanced_fields) valid = True if m._admin.inlines: for inlineopts in m._admin.inlines: inline = inlineopts.get("form") prefix = inlineopts.get("prefix") formset = inlineopts.get("formset") _temp = __import__('%s.forms' % app, globals(), locals(), [inline], 0) inline = getattr(_temp, inline) if formset: formset = getattr(_temp, formset) else: formset = FreeBaseInlineFormSet extrakw = {'can_delete': False} fset_fac = inlineformset_factory(m, inline._meta.model, form=inline, formset=formset, extra=0, **extrakw) try: fsname = 'formset_%s' % ( inline._meta.model._meta.model_name, ) fset = fset_fac(request.POST, prefix=prefix, parent=mf, instance=instance) formsets[fsname] = { 'instance': fset, 'position': inlineopts.get('position', 'bottom') } except dforms.ValidationError: pass for name, fsinfo in list(formsets.items()): for frm in fsinfo['instance'].forms: valid &= frm.is_valid() valid &= fsinfo['instance'].is_valid() valid &= mf.is_valid(formsets=formsets) if valid: if '__confirm' not in request.POST: message = self.get_confirm_message( 'add', obj=instance, form=mf, ) if message: return JsonResp( request, confirm=self.confirm(message), ) try: mf.save() if not isinstance(mf, MiddlewareModelForm): for name, fsinfo in list(formsets.items()): fsinfo['instance'].save() events = [] if hasattr(mf, "done") and callable(mf.done): mf.done(request=request, events=events) return JsonResp(request, form=mf, formsets=formsets, message=_("%s successfully updated.") % (m._meta.verbose_name, ), events=events) except ValidationErrors as e: handle_middleware_validation(mf, e) return JsonResp(request, form=mf, formsets=formsets) except ServiceFailed as e: return JsonResp( request, error=True, message=e.value, events=["serviceFailed(\"%s\")" % e.service]) except MiddlewareError as e: return JsonResp(request, error=True, message=_("Error: %s") % str(e)) else: return JsonResp(request, form=mf, formsets=formsets) else: mf = mf() if m._admin.advanced_fields: mf.advanced_fields.extend(m._admin.advanced_fields) if m._admin.inlines: extrakw = {'can_delete': False} for inlineopts in m._admin.inlines: inline = inlineopts.get("form") prefix = inlineopts.get("prefix") formset = inlineopts.get("formset") _temp = __import__('%s.forms' % app, globals(), locals(), [inline], 0) inline = getattr(_temp, inline) if formset: formset = getattr(_temp, formset) else: formset = FreeBaseInlineFormSet fset_fac = inlineformset_factory(m, inline._meta.model, form=inline, formset=formset, extra=1, **extrakw) fsname = 'formset_%s' % ( inline._meta.model._meta.model_name, ) fset = fset_fac(prefix=prefix, instance=instance, parent=mf) fset.verbose_name = (inline._meta.model._meta.verbose_name) formsets[fsname] = { 'instance': fset, 'position': inlineopts.get('position', 'bottom'), } context.update({ 'form': mf, 'formsets': formsets, }) context.update(self.get_extra_context('add', request=request, form=mf)) template = "%s/%s_add.html" % ( m._meta.app_label, m._meta.object_name.lower(), ) try: get_template(template) except TemplateDoesNotExist: template = 'freeadmin/generic_model_add.html' return render(request, template, context)
def save(self, bundle, skip_errors=False): # Check if they're authorized. if bundle.obj.pk: self.authorized_update_detail( self.get_object_list(bundle.request), bundle ) else: self.authorized_create_detail( self.get_object_list(bundle.request), bundle ) # Remove all "private" attributes data = dict(bundle.obj.__dict__) for key, val in list(data.items()): if key.startswith('_'): del data[key] continue # Add the pk of the foreign key in the mix if key.endswith('_id'): noid = key[:-3] field = getattr(bundle.obj.__class__, noid, None) if not field: continue if field and isinstance(field.field, ForeignKey): data[noid] = val del data[key] else: try: bundle.obj.__class__._meta.get_field(key) except FieldDoesNotExist: del data[key] data.update(bundle.data) bundle.data = data """ Get rid of None values, it means they were not passed to the API and will fail serialization """ querydict = data.copy() for key, val in list(querydict.items()): if val is None: del querydict[key] querydict = QueryDict(urllib.parse.urlencode(querydict, doseq=True)) # Allow one form validation for each method method_validation = '%s_validation' % bundle.request.method.lower() validation = getattr(self._meta, method_validation, self._meta.validation) form = validation.form_class( querydict, instance=bundle.obj, api_validation=True, ) if not self.is_form_valid(bundle, form): raise ImmediateHttpResponse(response=self.error_response( bundle.request, bundle.errors, response_class=http.HttpConflict, )) """ FIXME Saving the objects under a transaction won't work very well because some rc.d scripts and rc.conf will not be able to visualize the changes until the transaction is committed. # with transaction.atomic(): """ try: form.save() except ValidationErrors as e: handle_middleware_validation(form, e) raise ImmediateHttpResponse(response=self.error_response( bundle.request, form._errors, response_class=http.HttpConflict, )) self.post_form_save_hook(bundle, form) bundle.obj = form.instance bundle.objects_saved.add(self.create_identifier(bundle.obj)) # Now pick up the M2M bits. m2m_bundle = self.hydrate_m2m(bundle) self.save_m2m(m2m_bundle) if hasattr(form, 'done') and callable(form.done): form.done(request=bundle.request, events=[]) return bundle