def clean_key(self): """ Checks if the key is in settings. Used to avoid abuse of the form by enabling disabled form fields via firebug or similiar. """ key = self.cleaned_data['key'] try: settings.__getattr__(key) except AttributeError: raise forms.ValidationError(_("This key does not exists in the original settings.")) return key
def test_index_view_staff(self): logged_in = self.client.login(username=self.staff['username'], password=self.staff['password']) self.assertTrue(logged_in) response = self.client.get('/') self.assertEqual(response.status_code, 200) self.assertTrue('dynamic_settings' in response.context) self.assertTrue('STATIC_URL' in response.context) self.assertTrue('settings_form_rendered' in response.context) #check against a couple random settings which should be present for setting_dict in response.context['dynamic_settings']: self.assertEqual(setting_dict['type'], type(dynamic_settings.__getattr__(setting_dict['key'])).__name__, msg=setting_dict['key']) self.assertEqual(setting_dict['in_db'], False, msg=setting_dict['key']) #should be False at this moment self.assertEqual(setting_dict['can_change'], dynamic_settings.can_change(setting_dict['key']), msg=setting_dict['key']) self.client.logout()
def dynamicsettings_set(request): """A view to handle the POST request to set a setting in the database Params: - ``request``: a django http request object Returns: - a response as JSON including the following fields: - ``status``: "success" if the setting was saved in the database, "error" in other cases - on success: - ``value``: the new value of the setting (which is saved in the database) - ``type``: the new type of the setting, can only differ from the original type if it was ``NoneType`` - on error: - ``message``: the message describing the error - ``form``: the validated form rendered in a template (will show the error in the form) """ if request.method=='POST': response_dict = {} settings_form = forms.SettingsForm(request.POST) if settings_form.is_valid(): form_data = settings_form.cleaned_data changed = settings.set(form_data['key'], form_data['value'], form_data['type']) if changed is True: value = settings.__getattr__(form_data['key']) if isinstance(value, (list, tuple, dict)): value = simplejson.dumps(value, indent=4) response_dict.update({ 'status': 'success', 'value': value, 'type': form_data['type'], }) else: form_dict = {'settings_form': settings_form} form_dict.update(csrf_processor(request)) settings_form_rendered = template.loader.render_to_string('dynamicsettings/settings_form.html', form_dict) response_dict.update({ 'status': 'error', 'message': settings_form.errors['__all__'], 'form': settings_form_rendered }) return http.HttpResponse(simplejson.dumps(response_dict, indent=4), mimetype="text/plain") return http.HttpResponseNotAllowed(['GET', 'PUT', 'DELETE', 'HEAD', 'TRACE', 'OPTIONS', 'CONNECT', 'PATCH'])
def dynamicsettings_reset(request): """A view to handle the POST request to reset a setting in the database Params: - ``request``: a django http request object Returns: - a response as JSON including the following fields: - ``status``: "success" if the setting was reset in the database, "error" in other cases - on success: - ``value``: the original value of the setting (which is not saved in the database) - ``type``: the original type of the setting - on error: - ``message``: the message describing the error """ if request.method=='POST': key = request.POST.get('key', None) if key is None: response_dict = { 'status': 'error', 'message': _('No variable "key" in POST request.'), } else: reset_success = settings.reset(key) if reset_success is True: value = settings.__getattr__(key) if isinstance(value, (list, tuple, dict)): value = simplejson.dumps(value, indent=4) response_dict = { 'status': 'success', 'value': value, 'type': type(settings.get(key)).__name__, } else: response_dict = { 'status': 'error', 'message': _('The setting "%s" is not saved in the database or can not be reseted.' % request.POST['key']), } return http.HttpResponse(simplejson.dumps(response_dict, indent=4), mimetype="text/plain") return http.HttpResponseNotAllowed(['GET', 'PUT', 'DELETE', 'HEAD', 'TRACE', 'OPTIONS', 'CONNECT', 'PATCH'])
def clean(self): """ a) Check if the setting was originally from the submitted type. Used to avoid abuse of the form by enabling disabled form fields via firebug or similiar. b) Try to convert the value according to submitted type. Raises ValidiationError when type and value are not fitting each other (eg. value can;t be converted to type). c) check if the resulting value was actually changed (and not yet in the database) """ error_message_tmpl = 'A setting from type %s must be set to %s.' key = self.cleaned_data['key'] value = self.cleaned_data['value'] value_type = self.cleaned_data['type'] if settings.can_change(key) is False: raise forms.ValidationError(_("This setting can not be changed.")) #a) original_type = type(settings.__getattr__(key)).__name__ if original_type!='NoneType' and value_type!=original_type: raise forms.ValidationError(_("You can not change the type of a setting which was not NoneType before.")) #b) if value_type == 'NoneType': if value!='None': raise forms.ValidationError(_(error_message_tmpl % ('NoneType', '"None"'))) self.cleaned_data['value'] = None elif value_type == 'bool': if value!='True' and value!='False': raise forms.ValidationError(_(error_message_tmpl % ('bool', '"True" or "False"'))) if value!='True': self.cleaned_data['value'] = True elif value!='False': self.cleaned_data['value'] = False elif value_type == 'int': try: self.cleaned_data['value'] = int(value) except ValueError: raise forms.ValidationError(_(error_message_tmpl % ('int or long', 'a number'))) elif value_type == 'int': try: self.cleaned_data['value'] = float(value) except ValueError: raise forms.ValidationError(_(error_message_tmpl % ('float', 'a number'))) elif value_type == 'str': self.cleaned_data['value'] = value elif value_type == 'unicode': self.cleaned_data['value'] = unicode(value) elif value_type in ['tuple', 'list', 'dict']: try: self.cleaned_data['value'] = value = simplejson.loads(value) except ValueError: raise forms.ValidationError(_(error_message_tmpl % ('tuple, list or dict', 'a valid JSON string'))) if value_type == 'tuple' and type(value).__name__!='tuple': try: if type(value).__name__ == 'dict': raise TypeError self.cleaned_data['value'] = tuple(value) except (ValueError, TypeError): raise forms.ValidationError(_(error_message_tmpl % ('tuple', 'a valid JSON string representing an Array (leading "["and traling "]")'))) elif value_type == 'list' and type(value).__name__!='list': try: if type(value).__name__ == 'dict': raise TypeError self.cleaned_data['value'] = list(value) except (ValueError, TypeError): raise forms.ValidationError(_(error_message_tmpl % ('list', 'a valid JSON string representing an Array (leading "["and traling "]")'))) elif value_type == 'dict' and type(value).__name__!='dict': try: if type(value).__name__ == 'list': raise TypeError self.cleaned_data['value'] = dict(value) except (ValueError, TypeError): raise forms.ValidationError(_(error_message_tmpl % ('dict', 'a valid JSON string representing an Object (leading "{"and traling "}")'))) #c) value = self.cleaned_data['value'] if not settings.is_in_db(key) and value==settings.__getattr__(key): raise forms.ValidationError(_('To save a setting in the database the value must have been changed from its original value.')) return self.cleaned_data