def error( self, request, status_code, error_dict=None, ): """ Handles errors in a RESTful way. - appropriate status code - appropriate mimetype - human-readable error message """ if not error_dict: error_dict = ErrorDict() response = HttpResponse(mimetype=self.mimetype) response.write('%d %s' % (status_code, STATUS_CODE_TEXT[status_code])) if error_dict: response.write(''' Errors: ''') response.write(error_dict.as_text()) response.status_code = status_code return response
def error(self, request, status_code, error_dict=None): """ Return XML error response that includes a human readable error message, application-specific errors and a machine readable status code. """ from django.conf import settings if not error_dict: error_dict = ErrorDict() response = HttpResponse(mimetype = self.mimetype) response.status_code = status_code xml = SimplerXMLGenerator(response, settings.DEFAULT_CHARSET) xml.startDocument() xml.startElement("django-error", {}) xml.addQuickElement(name="error-message", contents='%d %s' % (status_code, STATUS_CODE_TEXT[status_code])) xml.addQuickElement(name="status-code", contents=str(status_code)) if error_dict: xml.startElement("model-errors", {}) for (model_field, errors) in error_dict.items(): for error in errors: xml.addQuickElement(name=model_field, contents=error) xml.endElement("model-errors") xml.endElement("django-error") xml.endDocument() return response
def render(self, context): form = self.form.resolve(context, True) hidden_fields_errors = ErrorDict() for field in form.hidden_fields(): if field.errors: hidden_fields_errors.update({field.name: field.errors}) context[self.as_var] = hidden_fields_errors return ""
def update_ns(request, nameserver_pk): nameserver = get_object_or_404(Nameserver, pk=nameserver_pk) if request.method == "POST": form = NameserverForm(request.POST, instance=nameserver) try: if form.is_valid(): server = form.cleaned_data['server'] domain = form.cleaned_data['domain'] if 'glue' in form.cleaned_data: glue_type, glue_pk = form.cleaned_data['glue'].split('_') try: if glue_type == 'addr': glue = AddressRecord.objects.get(pk=glue_pk) elif glue_type == 'sreg': glue = StaticReg.objects.get(pk=glue_pk) except ObjectDoesNotExist, e: raise ValidationError("Couldn't find glue: " + str(e)) nameserver.glue = glue nameserver.server = server nameserver.domain = domain nameserver.clean() nameserver.save() except ValidationError, e: form = Nameserver(instance=nameserver) if form._errors is None: form._errors = ErrorDict() form._errors['__all__'] = ErrorList(e.messages) return redirect(nameserver)
def _create_ipv4_intr_from_range(label, domain_name, system, mac, range_start, range_end): if range_start >= range_end - 1: errors = {} errors['ip'] = ErrorList(["The start ip must be less than end ip."]) return None, errors ip = find_free_ip(range_start, range_end, ip_type='4') errors = ErrorDict() if not ip: errors['ip'] = ErrorList([ "Could not find free ip in range {0} - " "{1}".format(range_start, range_end) ]) return None, errors domain = ensure_domain(domain_name, inherit_soa=True) try: intr = StaticInterface(label=label, domain=domain, ip_str=str(ip), ip_type='4', system=system, mac=mac) intr.clean() except ValidationError, e: errors['interface'] = ErrorList(e.messages)
def error(self, request, status_code, error_dict=None): """ Handles errors in a RESTful way. - appropriate status code - appropriate mimetype - human-readable error message """ if not error_dict: error_dict = ErrorDict() response = HttpResponse(mimetype = self.mimetype) response.write('%d %s' % (status_code, STATUS_CODE_TEXT[status_code])) if error_dict: response.write('\n\nErrors:\n') response.write(error_dict.as_text()) response.status_code = status_code return response
def security_errors(self): """Return just those errors associated with security""" errors = ErrorDict() for f in ["honeypot", "timestamp", "security_hash"]: if f in self.errors: errors[f] = self.errors[f] return errors
def is_valid(self): is_valid = super(CreateDataStreamForm, self).is_valid() is_valid = is_valid and self.tag_formset.is_valid() is_valid = is_valid and self.source_formset.is_valid() is_valid = is_valid and self.parameter_formset.is_valid() # Django does not allow to change form.errors, so we use form._errors if not is_valid: if self.tag_formset._errors or self.source_formset._errors or self.parameter_formset._errors: self._errors = dict(self._errors) for error in self.tag_formset._errors: self._errors.update(dict(error)) for error in self.source_formset._errors: self._errors.update(dict(error)) for error in self.parameter_formset._errors: self._errors.update(dict(error)) self._errors = ErrorDict(self._errors) else: self.cleaned_data['tags'] = [ form.cleaned_data for form in self.tag_formset ] self.cleaned_data['sources'] = [ form.cleaned_data for form in self.source_formset ] self.cleaned_data['parameters'] = [ form.cleaned_data for form in self.parameter_formset ] return is_valid
def _post_clean(self): """ Rewrite the error dictionary, so that its keys correspond to the model fields. """ super(NgModelFormMixin, self)._post_clean() if self._errors and self.prefix: self._errors = ErrorDict((self.add_prefix(name), value) for name, value in self._errors.items())
class RentalReservationLineEditItemForm(forms.ModelForm): class Meta: model = RentalReservationLineItem fields = ("product", "qty") def clean_qty(self): qty = self.cleaned_data.get("qty") if qty <= 0: raise ValidationError("Reservation qty must be greater than 0") return qty def validate_qty(self, facility, start_time, end_time): qty = self.instance.qty product = self.instance.product # if form corresponds to existing ReservationLineItem being changed, get previous scheduled_adjustment_id existing_adjustment_id = self.instance.pk or None # have to ignore previous scheduled_adjustment qty when determining if sufficient inventory exists min_inventory_during_reservation = \ facility.get_min_expected_inventory_in_interval(product.id, start_time, end_time, scheduled_adjustment_exclude_id=existing_adjustment_id) if min_inventory_during_reservation - qty < 0: if not self._errors: self._errors = ErrorDict() qty_errors = self._errors.setdefault("qty", ErrorList()) expanded_search_buffer = timedelta(hours=5) inventory_search_start = start_time - expanded_search_buffer inventory_search_end = end_time + expanded_search_buffer expected_inventory_url = expected_inventory_url_with_querystring(product, facility, inventory_search_start, inventory_search_end) error_message = mark_safe("Only expected to have {} available at reservation time. Want to <a href='{}' target='_blank'>check</a> when more will be available?".format(min_inventory_during_reservation, expected_inventory_url)) qty_errors.append(error_message)
def field_errors(self): """ Returns a dictionary containing only field-related errors. """ error_dict = copy.copy(self._errors) if not error_dict: error_dict = ErrorDict() if NON_FIELD_ERRORS in error_dict: del error_dict[NON_FIELD_ERRORS] return error_dict
def edit(request, pk=1, errors=None, reverse=False): """Edit main profile data if user is authorized""" template = 'profiles/edit.html' result = 'Error' if errors is None: errors = ErrorDict() target = Profile.objects.get(pk=pk) if request.method == 'POST' and request.user.is_authenticated(): profile = ProfileForm(request.POST, request.FILES, instance=target) contacts = ContactFormSet(request.POST, request.FILES, instance=target) if profile.is_valid() and contacts.is_valid(): contacts.save() profile.save() result = 'Done' if not profile.is_valid(): errors.update(profile.errors) if not contacts.is_valid(): for num, suberrors in enumerate(contacts.errors): if suberrors: for field, error in suberrors.iteritems(): field_id = "%s-%s-%s" % (contacts.prefix, num, field) errors.update({field_id: error}) if (request.method == 'GET' or not request.user.is_authenticated() or errors): profile = ProfileForm(instance=target) contacts = ContactFormSet(instance=target) if reverse: profile.fields.keyOrder.reverse() contacts.forms.reverse() template = 'profiles/edit_reversed.html' if not request.user.is_authenticated(): readonly(profile) readonly(contacts) errors['auth: '] = 'you are not authorized to edit this form' if request.is_ajax(): return HttpResponse(simplejson.dumps({'result': result, 'errors': errors}), mimetype='application/javascript') else: print(errors) return render_to_response(template, {'profile': profile, 'contacts': contacts, 'errors': errors}, context_instance=RequestContext(request))
def full_clean(self): if not self.find_enabled_value(): self.cleaned_data = { 'enabled': False, } self._errors = ErrorDict() else: return super(AccountForm, self).full_clean()
def error(self, request, status_code, error_dict=None): """ Return JSON error response that includes a human readable error message, application-specific errors and a machine readable status code. """ if not error_dict: error_dict = ErrorDict() response = HttpResponse(mimetype = self.mimetype) response.status_code = status_code response_dict = { "error-message" : '%d %s' % (status_code, STATUS_CODE_TEXT[status_code]), "status-code" : status_code, "model-errors" : error_dict.as_ul() } simplejson.dump(response_dict, response) return response
def test_clean(self): fs = FormSetMixin() form_a = Mock() form_a.cleaned_data = {"DELETE": True} form_a._errors = ErrorDict({"name": "That's not a valid name"}) form_b = Mock() form_b.cleaned_data = {"name": "John"} form_b._errors = ErrorDict() form_c = Mock() form_c.cleaned_data = {} form_c._errors = ErrorDict({"name": "That's not a valid name"}) fs.forms = [form_a, form_b, form_c] fs.clean() self.assertEqual(form_a._errors, ErrorDict())
def error_response(error_code, error_message, error_class, error_dict=None): resp_dict = {} # response = HttpResponse() response = HttpResponseServerError() resp_dict['error code'] = error_code resp_dict['error message'] = error_message resp_dict['error class'] = error_class # if error_code == 500: # response.status_code = error_code if error_dict: error_dict = ErrorDict(error_dict) resp_dict['error message'] += '\n%s' % error_dict.as_text() logger.debug('resp_dict%s' % resp_dict) response.write(json.dumps(resp_dict)) logger.debug('response.content %s' % response.content) return response
def clean(self): """ When cleaning, if the form is being deleted, any errors on it should be ignored """ for form in self.forms: # this form is being deleted, so overwrite the errors if form.cleaned_data.get("DELETE"): form._errors = ErrorDict()
def _errors(self): if self.__errors is None: error_dict = ErrorDict() for f in self._forms: error_dict[self._forms.index(f)] = f.errors if self._nf_errors: error_dict[NON_FIELD_ERRORS]=self._nf_errors self.__errors = error_dict return self.__errors
def full_clean(self): """ Like Django's but we don't delete cleaned_data on error. """ self._errors = ErrorDict() if not self.is_bound: # Stop further processing. return self.cleaned_data = {} # If the form is permitted to be empty, and none of the form data has # changed from the initial data, short circuit any validation. if self.empty_permitted and not self.has_changed(): return self._clean_fields() self._clean_form() self._post_clean() # Errors are for data-prudes for field in self._errors.keys(): self.cleaned_data[field] = '' self._errors = ErrorDict()
def _validate_file_size(request, form, klass): # check whether file is too large upload_limit = Preferences.objects.get(pk=1).max_data_size if klass in (Data, Task) and 'file' in request.FILES: if len(request.FILES['file']) > upload_limit: form.errors['file'] = ErrorDict({ '': _('File is too large! Must be smaller than %dMB!' % (upload_limit / MEGABYTE)) }).as_ul()
def nice_errors(form, non_field_msg='General form errors'): this_nice_errors = ErrorDict() if isinstance(form, forms.BaseForm): for field, errors in form.errors.items(): if field == NON_FIELD_ERRORS: key = non_field_msg else: key = form.fields[field].label this_nice_errors[key] = errors return this_nice_errors
def error_response( error_code, error_message, error_class, error_dict = None): resp_dict = {} # response = HttpResponse() response = HttpResponseServerError() resp_dict['error code'] = error_code resp_dict['error message'] = error_message resp_dict['error class'] = error_class # if error_code == 500: # response.status_code = error_code if error_dict: error_dict = ErrorDict(error_dict) resp_dict['error message'] += '\n%s'%error_dict.as_text() logger.debug('resp_dict%s' %resp_dict) response.write(json.dumps(resp_dict)) logger.debug('response.content %s' %response.content) return response
def full_clean(self): """Override the django implementation - we don't want to delete the cleaned_data if the form is not valid. """ self._errors = ErrorDict() if not self.is_bound: # Stop further processing. return self.cleaned_data = {} self._clean_fields() self._clean_form() self._post_clean()
def clean(self): cleaned_data = super(DeleteFormMixin, self).clean() # If this object is set to be deleted, validation doesn't matter # because the object will be delete anyway so remove all errors so it # passes validation. if self.cleaned_data.get('delete') is True: self._errors = ErrorDict() return cleaned_data
def modify_qd(self, qd, object_=None): fqdn = qd.pop('fqdn', [''])[0] domain = None # if record_type not in ('PTR', 'NS', 'DOMAIN', 'SOA'): try: label, domain = ensure_label_domain(fqdn) # If something goes bad latter on you must call prune_tree on # domain. If you don't do this there will be a domain leak. except ValidationError, e: errors = ErrorDict() errors['fqdn'] = e.messages return None, errors
def modify_qd(self, qd, **kwargs): domain_pk = qd.pop('domain', '')[0] try: domain = Domain.objects.get(pk=domain_pk) qd['domain'] = str(domain.pk) except Domain.DoesNotExist: error_message = _("Could not find domain with pk " "'{0}'".format(domain_pk)) errors = ErrorDict() errors['domain'] = [error_message] return None, errors return qd, None
def error(self, request, status_code, error_dict=None): """ Renders error template (template name: error status code). """ if not error_dict: error_dict = ErrorDict() response = direct_to_template(request, template = '%s/%s.html' % (self.template_dir, str(status_code)), extra_context = { 'errors' : error_dict }, mimetype = self.mimetype) response.status_code = status_code return response
def cydns_view(request, pk=None): """List, create, update view in one for a flatter heirarchy. """ # Infer obj_type from URL, saves trouble of having to specify # kwargs everywhere in the dispatchers. obj_type = request.path.split('/')[2] # Get the record form. Klass, FormKlass, FQDNFormKlass = get_klasses(obj_type) # Get the object if updating. record = get_object_or_404(Klass, pk=pk) if pk else None form = FQDNFormKlass(instance=record) if request.method == 'POST': qd, domain, errors = _fqdn_to_domain(request.POST.copy()) # Validate form. if errors: print errors fqdn_form = FQDNFormKlass(request.POST) fqdn_form._errors = ErrorDict() fqdn_form._errors['__all__'] = ErrorList(errors) return render(request, 'cydns/cydns_view.html', { 'form': fqdn_form, 'obj_type': obj_type, 'pk': pk, 'obj': record }) else: form = FormKlass(qd, instance=record) try: if perm(request, cy.ACTION_CREATE, obj=record, obj_class=Klass): record = form.save() # If domain, add to current ctnr. if obj_type == 'domain': request.session['ctnr'].domains.add(record) return redirect(record.get_list_url()) except (ValidationError, ValueError): form = _revert(domain, request.POST, form, FQDNFormKlass) object_list = _filter(request, Klass) page_obj = make_paginator(request, do_sort(request, object_list), 50) return render( request, 'cydns/cydns_view.html', { 'form': form, 'obj': record, 'page_obj': page_obj, 'object_table': tablefy(page_obj, views=True), 'obj_type': obj_type, 'pk': pk, })
def update_range(request, range_pk): mrange = get_object_or_404(Range, pk=range_pk) attrs = mrange.rangekeyvalue_set.all() docs = get_docstrings(RangeKeyValue()) aa = get_aa(RangeKeyValue()) if request.method == 'POST': form = RangeForm(request.POST, instance=mrange) try: if not form.is_valid(): if form._errors is None: form._errors = ErrorDict() form._errors['__all__'] = ErrorList(e.messages) return render(request, 'range/range_edit.html', { 'range': mrange, 'form': form, 'attrs': attrs, 'docs': docs, 'aa': json.dumps(aa) }) else: # Handle key value stuff. kv = None kv = get_attrs(request.POST) update_attrs(kv, attrs, RangeKeyValue, mrange, 'range') mrange = form.save() return redirect(mrange.get_update_url()) except ValidationError, e: if form._errors is None: form._errors = ErrorDict() if kv: attrs = dict_to_kv(kv, RangeKeyValue) form._errors['__all__'] = ErrorList(e.messages) return render(request, 'range/range_edit.html', { 'range': mrange, 'form': form, 'attrs': attrs, 'docs': docs, 'aa': json.dumps(aa) })
def create(self, request): """ lets the user post new activity in a giant single array of activity log elements """ request_user = basicauth_get_user_by_emailaddr(request) if not request_user: logevent(request, 'ActivityLog.create POST', 401, jv3.utils.decode_emailaddr(request)) return self.responder.error( request, 401, ErrorDict({"autherror": "Incorrect user/password combination"})) # clientid = self._get_client(request) # this doesn't work, emax clientid = None maxdate, count = self._get_max_helper(request_user, clientid) # overcount committed = [] incoming = JSONDecoder().decode(request.raw_post_data) print "activity log", request_user, " received ", len(incoming) dupes = 0 for item in incoming: #print "item is %s " % repr(item) try: if ActivityLog.objects.filter(owner=request_user, when=item['id'], action=item['type']).count() > 0: # print "actlog skipping ~ " dupes = dupes + 1 continue entry = ActivityLog() entry.owner = request_user entry.when = item['id'] entry.action = item['type'] entry.noteid = item.get("noteid", None) entry.noteText = item.get("noteText", None) entry.search = item.get("search", None) entry.client = item.get("client", None) ## added in new rev clientid = item.get("client") entry.save() committed.append(long(item['id'])) maxdate = max(maxdate, long(item['id'])) except StandardError, error: print "Error with entry %s item %s " % (repr(error), repr(item))
def __call__(self, admin, request, form, **data): if not self.added: return self.validator(admin, request, form, **data) if form._errors is None: frozenerrors = ErrorDict() else: frozenerrors = form._errors.copy() frozendata = form.cleaned_data.copy() or_validators = self.or_validators if not any([v(admin, request, form, **data) for v in self.or_validators]): return False form._errors = frozenerrors form.cleaned_data = frozendata return all([v(admin, request, form, **data) for v in self.and_validators])
def full_clean(self): super(TranslationModelForm, self).full_clean() if self._errors: self.cleaned_data = {} self.child_form.full_clean() if self.child_form._errors: if not self._errors: self._errors = ErrorDict() for k, v in list(self.child_form._errors.items()): if k in self._errors and k != NON_FIELD_ERRORS: # remove existing errors so there are no duplicates del self._errors[k] self._update_errors(self.child_form._errors) del self.cleaned_data
def __call__(self, request, format, *args, **kwargs): ''' urls.py must contain .(?P<format>\w+) at the end of the url for rest resources, such that it would match one of the keys in self.responders ''' error_code = 400 errors = ErrorDict({'info': ["An error has occured"]}) if format in self.responders: self.responder = self.responders[format] try: return Collection.__call__(self, request, *args, **kwargs) except search.SearchAddressDisambiguateError, e: return self.responder.error( request, 412, ErrorDict({ 'info': [str(e)], 'possible_addresses': addrs })) except InputValidationException, e: errors = ErrorDict({'info': [str(e)]}) error_code = 412
def full_clean(self): """ Cleans all of self.data and populates self._errors and self.cleaned_data. """ self._errors = ErrorDict() if not self.is_bound: # Stop further processing. return self.cleaned_data = {} # If the form is permitted to be empty, and none of the form data has # changed from the initial data, short circuit any validation. if self.empty_permitted and not self.has_changed(): return self._clean_fields() self._clean_form() self._post_clean()
def full_clean(self): """ Cleans all of self.data and populates self._errors and self.cleaned_data. """ self._errors = ErrorDict() if not self.is_bound: return self.cleaned_data = {} if self.empty_permitted and not self.has_changed(): return self._clean_fields() self._clean_form() self._post_clean()
def is_valid(self): is_valid = super(WebserviceForm, self).is_valid() is_valid = is_valid and self.param_formset.is_valid() if not is_valid: # Django does not allow to change form.errors, so we use form._errors if self.param_formset: if self.param_formset._errors: self._errors = dict(self._errors) for error in self.param_formset._errors: self._errors.update(dict(error)) self._errors = ErrorDict(self._errors) self.cleaned_data['parameters'] = [form.cleaned_data for form in self.param_formset] if (int(self.cleaned_data['impl_type']) == choices.SourceImplementationChoices.REST and settings.PUBLICSTUFF_DOMAIN in self.cleaned_data['end_point']): self.cleaned_data['impl_type'] = choices.SourceImplementationChoices.PUS return is_valid
def is_valid(self): is_valid = super(WebserviceForm, self).is_valid() is_valid = is_valid and self.param_formset.is_valid() if not is_valid: # Django does not allow to change form.errors, so we use form._errors if self.param_formset: if self.param_formset._errors: self._errors = dict(self._errors) for error in self.param_formset._errors: self._errors.update(dict(error)) self._errors = ErrorDict(self._errors) self.cleaned_data['parameters'] = [ form.cleaned_data for form in self.param_formset ] return is_valid
class ReporterSearchForm(forms.Form): q = forms.CharField(required=False, label='', widget=SearchInput( attrs={'placeholder': _lazy('Search by keyword')})) product = forms.ChoiceField(choices=PROD_CHOICES, label=_lazy('Product:'), initial=FIREFOX.short, required=False) version = forms.ChoiceField(required=False, label=_lazy('Version:'), choices=VERSION_CHOICES[FIREFOX]) sentiment = forms.ChoiceField(required=False, label=_lazy('Sentiment:'), choices=SENTIMENT_CHOICES) locale = forms.ChoiceField(required=False, label=_lazy('Locale:'), choices=LOCALE_CHOICES) platform = forms.ChoiceField(required=False, label=_lazy('PLATFORM:'), choices=PLATFORM_CHOICES) manufacturer = forms.ChoiceField(required=False, choices=MANUFACTURER_CHOICES) device = forms.ChoiceField(required=False, choices=DEVICE_CHOICES) date_start = forms.DateField(required=False, widget=DateInput( attrs={'class': 'datepicker'}), label=_lazy('Date range:')) date_end = forms.DateField(required=False, widget=DateInput( # L10n: This indicates the second part of a date range. attrs={'class': 'datepicker'}), label=_lazy('to')) page = forms.IntegerField(widget=forms.HiddenInput, required=False) # TODO(davedash): Make this prettier. def __init__(self, *args, **kwargs): """Pick version choices and initial product based on site ID.""" super(ReporterSearchForm, self).__init__(*args, **kwargs) self.fields['version'].choices = VERSION_CHOICES[FIREFOX] # Show Mobile versions if that was picked by the user. picked = None if self.is_bound: try: picked = self.fields['product'].clean(self.data.get('product')) except forms.ValidationError: pass if (picked == MOBILE.short or not self.is_bound and settings.SITE_ID == settings.MOBILE_SITE_ID): # We default to Firefox. Only change if this is the mobile site. self.fields['product'].initial = MOBILE.short self.fields['version'].choices = VERSION_CHOICES[MOBILE] def clean(self): cleaned = self.cleaned_data # default date_end to today if (self.cleaned_data.get('date_start') and not self.cleaned_data.get('date_end')): self.cleaned_data['date_end'] = date.today() # Flip start and end if necessary. if (cleaned.get('date_start') and cleaned.get('date_end') and cleaned['date_start'] > cleaned['date_end']): (cleaned['date_start'], cleaned['date_end']) = ( cleaned['date_end'], cleaned['date_start']) # Ensure page is a natural number. try: cleaned['page'] = int(cleaned.get('page')) assert cleaned['page'] > 0 except (TypeError, AssertionError): cleaned['page'] = 1 if not cleaned.get('version'): cleaned['version'] = (getattr(FIREFOX, 'default_version', None) or Version(LATEST_BETAS[FIREFOX]).simplified) elif cleaned['version'] == '--': cleaned['version'] = '' return cleaned def full_clean(self): """ Like Django's but we don't delete cleaned_data on error. """ self._errors = ErrorDict() if not self.is_bound: # Stop further processing. return self.cleaned_data = {} # If the form is permitted to be empty, and none of the form data has # changed from the initial data, short circuit any validation. if self.empty_permitted and not self.has_changed(): return self._clean_fields() self._clean_form() self._post_clean() # Errors are for data-prudes for field in self._errors.keys(): self.cleaned_data[field] = '' self._errors = ErrorDict()
class NgModelFormMixin(NgFormBaseMixin): """ Add this NgModelFormMixin to every class derived from forms.Form, if you want to manage that form through an Angular controller. It adds attributes ng-model, and optionally ng-change, ng-class and ng-style to each of your input fields. If form validation fails, the ErrorDict is rewritten in a way, so that the Angular controller can access the error strings using the same key values as for its models. """ def __init__(self, data=None, *args, **kwargs): self.scope_prefix = kwargs.pop('scope_prefix', getattr(self, 'scope_prefix', None)) if hasattr(self, 'Meta') and hasattr(self.Meta, 'ng_models'): if not isinstance(self.Meta.ng_models, list): raise TypeError('Meta.ng_model is not of type list') ng_models = self.Meta.ng_models else: ng_models = None directives = {} for key in list(kwargs.keys()): if key.startswith('ng_'): fmtstr = kwargs.pop(key) directives[key.replace('_', '-')] = fmtstr if ng_models is None and 'ng-model' not in directives: directives['ng-model'] = '%(model)s' self.prefix = kwargs.get('prefix') if self.prefix and data: data = dict((self.add_prefix(name), value) for name, value in data.get(self.prefix).items()) for name, field in self.base_fields.items(): identifier = self.add_prefix(name) ng = { 'name': name, 'identifier': identifier, 'model': self.scope_prefix and ('%s.%s' % (self.scope_prefix, identifier)) or identifier } if ng_models and name in ng_models: field.widget.attrs['ng-model'] = ng['model'] for key, fmtstr in directives.items(): field.widget.attrs[key] = fmtstr % ng try: if isinstance(data, QueryDict): data = field.implode_multi_values(name, data.copy()) except AttributeError: pass super(NgModelFormMixin, self).__init__(data, *args, **kwargs) if self.scope_prefix == self.form_name: raise ValueError("The form's name may not be identical with its scope_prefix") def _post_clean(self): """ Rewrite the error dictionary, so that its keys correspond to the model fields. """ super(NgModelFormMixin, self)._post_clean() if self._errors and self.prefix: self._errors = ErrorDict((self.add_prefix(name), value) for name, value in self._errors.items()) def get_initial_data(self): """ Return a dictionary specifying the defaults for this form. This dictionary shall be used to inject the initial values for an Angular controller using the directive 'ng-init={{thisform.get_initial_data|js|safe}}'. """ data = {} for name, field in self.fields.items(): if hasattr(field, 'widget') and 'ng-model' in field.widget.attrs: data[name] = self.initial and self.initial.get(name) or field.initial return data def get_field_errors(self, field): errors = super(NgModelFormMixin, self).get_field_errors(field) identifier = format_html('{0}.{1}', self.form_name, field.name) errors.append(SafeTuple((identifier, '$pristine', '$message', 'invalid', '$message'))) return errors def non_field_errors(self): errors = super(NgModelFormMixin, self).non_field_errors() errors.append(SafeTuple((self.form_name, '$pristine', '$message', 'invalid', '$message'))) return errors
class NgModelFormMixin(NgFormBaseMixin): """ Add this NgModelFormMixin to every class derived from ``forms.Form``, if that custom ``Form`` shall be managed through an Angular controller. It adds attributes ``ng-model``, and optionally ``ng-change``, ``ng-class`` and ``ng-style`` to each of your input fields. If form validation fails, the ErrorDict is rewritten in a way, so that the Angular controller can access the error strings using the same key values as for its models. """ add_djng_error = False def __init__(self, data=None, *args, **kwargs): self.scope_prefix = kwargs.pop('scope_prefix', getattr(self, 'scope_prefix', None)) self.ng_directives = {} for key in list(kwargs.keys()): if key.startswith('ng_'): fmtstr = kwargs.pop(key) self.ng_directives[key.replace('_', '-')] = fmtstr if hasattr(self, 'Meta') and hasattr(self.Meta, 'ng_models'): if not isinstance(getattr(self.Meta, 'ng_models'), list): raise TypeError('Meta.ng_model is not of type list') elif 'ng-model' not in self.ng_directives: self.ng_directives['ng-model'] = '%(model)s' self.prefix = kwargs.get('prefix') if self.prefix and data: data = dict((self.add_prefix(name), value) for name, value in data.get(self.prefix).items()) super(NgModelFormMixin, self).__init__(data, *args, **kwargs) if self.scope_prefix == self.form_name: raise ValueError("The form's name may not be identical with its scope_prefix") def _post_clean(self): """ Rewrite the error dictionary, so that its keys correspond to the model fields. """ super(NgModelFormMixin, self)._post_clean() if self._errors and self.prefix: self._errors = ErrorDict((self.add_prefix(name), value) for name, value in self._errors.items()) def get_initial_data(self): """ Return a dictionary specifying the defaults for this form. This dictionary can be used to inject the initial values for an Angular controller using the directive: ``ng-init={{ thisform.get_initial_data|js|safe }}``. """ data = {} ng_models = hasattr(self, 'Meta') and getattr(self.Meta, 'ng_models', []) or [] for name, field in self.fields.items(): if 'ng-model' in self.ng_directives or name in ng_models: data[name] = self.initial and self.initial.get(name) or field.initial return data def get_field_errors(self, field): errors = super(NgModelFormMixin, self).get_field_errors(field) if field.is_hidden: return errors identifier = format_html('{0}.{1}', self.form_name, field.name) errors.append(SafeTuple((identifier, self.field_error_css_classes, '$pristine', '$message', 'invalid', '$message'))) return errors def non_field_errors(self): errors = super(NgModelFormMixin, self).non_field_errors() errors.append(SafeTuple((self.form_name, self.form_error_css_classes, '$pristine', '$message', 'invalid', '$message'))) return errors def get_widget_attrs(self, bound_field): attrs = super(NgModelFormMixin, self).get_widget_attrs(bound_field) identifier = self.add_prefix(bound_field.name) ng = { 'name': bound_field.name, 'identifier': identifier, 'model': self.scope_prefix and ('%s.%s' % (self.scope_prefix, identifier)) or identifier } if hasattr(self, 'Meta') and bound_field.name in getattr(self.Meta, 'ng_models', []): attrs['ng-model'] = ng['model'] for key, fmtstr in self.ng_directives.items(): attrs[key] = fmtstr % ng return attrs
class NgModelFormMixin(NgFormBaseMixin): """ Add this NgModelFormMixin to every class derived from forms.Form, if you want to manage that form through an Angular controller. It adds attributes ng-model, and optionally ng-change, ng-class and ng-style to each of your input fields. If form validation fails, the ErrorDict is rewritten in a way, so that the Angular controller can access the error strings using the same key values as for its models. """ def __init__(self, data=None, *args, **kwargs): self.scope_prefix = kwargs.pop("scope_prefix", getattr(self, "scope_prefix", None)) self.ng_directives = {} for key in list(kwargs.keys()): if key.startswith("ng_"): fmtstr = kwargs.pop(key) self.ng_directives[key.replace("_", "-")] = fmtstr if hasattr(self, "Meta") and hasattr(self.Meta, "ng_models"): if not isinstance(getattr(self.Meta, "ng_models"), list): raise TypeError("Meta.ng_model is not of type list") elif "ng-model" not in self.ng_directives: self.ng_directives["ng-model"] = "%(model)s" self.prefix = kwargs.get("prefix") if self.prefix and data: data = dict((self.add_prefix(name), value) for name, value in data.get(self.prefix).items()) super(NgModelFormMixin, self).__init__(data, *args, **kwargs) if self.scope_prefix == self.form_name: raise ValueError("The form's name may not be identical with its scope_prefix") def _post_clean(self): """ Rewrite the error dictionary, so that its keys correspond to the model fields. """ super(NgModelFormMixin, self)._post_clean() if self._errors and self.prefix: self._errors = ErrorDict((self.add_prefix(name), value) for name, value in self._errors.items()) def get_initial_data(self): """ Return a dictionary specifying the defaults for this form. This dictionary can be used to inject the initial values for an Angular controller using the directive: ``ng-init={{ thisform.get_initial_data|js|safe }}``. """ data = {} ng_models = hasattr(self, "Meta") and getattr(self.Meta, "ng_models", []) or [] for name, field in self.fields.items(): if "ng-model" in self.ng_directives or name in ng_models: data[name] = self.initial and self.initial.get(name) or field.initial return data def get_field_errors(self, field): errors = super(NgModelFormMixin, self).get_field_errors(field) if field.is_hidden: return errors identifier = format_html("{0}.{1}", self.form_name, field.name) errors.append( SafeTuple((identifier, self.field_error_css_classes, "$pristine", "$message", "invalid", "$message")) ) return errors def non_field_errors(self): errors = super(NgModelFormMixin, self).non_field_errors() errors.append( SafeTuple((self.form_name, self.form_error_css_classes, "$pristine", "$message", "invalid", "$message")) ) return errors def get_widget_attrs(self, bound_field): identifier = self.add_prefix(bound_field.name) ng = { "name": bound_field.name, "identifier": identifier, "model": self.scope_prefix and ("%s.%s" % (self.scope_prefix, identifier)) or identifier, } attrs = {} if hasattr(self, "Meta") and bound_field.name in getattr(self.Meta, "ng_models", []): attrs["ng-model"] = ng["model"] for key, fmtstr in self.ng_directives.items(): attrs[key] = fmtstr % ng return attrs
def new(request, klass, default_arg=None): """Create a new item of given klass. @param request: request data @type request: Django request @param klass: item's class for lookup in correct database table @type klass: either Data, Task or Method @return: user login page, item's view page or this page again on failed form validation @rtype: Django response @raise Http404: if given klass is unexpected """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('user_signin') + '?next=' + request.path) upload_limit = Preferences.objects.get(pk=1).max_data_size formfunc = eval(klass.__name__ + 'Form') if request.method == 'POST': form = formfunc(request.POST, request.FILES, request=request) # manual validation coz it's required for new, but not edited Data if not request.FILES and klass == Data: form.errors['file'] = ErrorDict({'': _('This field is required.')}).as_ul() _validate_file_size(request, form, klass) if form.is_valid(): new = form.save(commit=False) new.pub_date = datetime.datetime.now() try: new.slug = new.make_slug() except IntegrityError: # looks quirky... d = ErrorDict({'': _('The given name yields an already existing slug. Please try another name.')}) form.errors['name'] = d.as_ul() else: new.version = 1 new.is_current = True new.is_public = False new.user = request.user if not form.cleaned_data['keep_private']: new.is_public = True if klass == Data: _upload_data_file(new, request.FILES['file']) new.save() form.save_m2m() # it couldn't be done automatically because of commit=False elif klass == Task: new.license = FixedLicense.objects.get(pk=1) # fixed to CC-BY-SA taskinfo = { 'train_idx': (form.cleaned_data['train_idx']), 'val_idx': (form.cleaned_data['val_idx']), 'test_idx': (form.cleaned_data['test_idx']), 'input_variables': form.cleaned_data['input_variables'], 'output_variables': form.cleaned_data['output_variables'], 'data_size': form.cleaned_data['data'].num_instances } new.file = None if 'file' in request.FILES: new.file = request.FILES['file'] new.save() new.create_next_file(prev=None) else: new.save(taskinfo=taskinfo) elif klass == Method: #if 'score' in request.FILES: # new.score = request.FILES['score'] # new.score.name = new.get_scorename() new.license = FixedLicense.objects.get(pk=1) # fixed to CC-BY-SA new.save() elif klass == Challenge: new.license = FixedLicense.objects.get(pk=1) # fixed to CC-BY-SA new.save() new.task=form.cleaned_data['task'] new.save() else: raise Http404 return HttpResponseRedirect(new.get_absolute_slugurl()) else: if default_arg: form = formfunc(request=request, default_arg=default_arg) else: form = formfunc(request=request) kname=klass.__name__.lower() info_dict = { 'klass': klass.__name__, kname: True, 'uuid': uuid.uuid4(), # for upload progress bar 'url_new': request.path, 'form': form, 'request': request, 'tagcloud': get_tag_clouds(request), 'section': 'repository', 'upload_limit': "%dMB" % (upload_limit / MEGABYTE) } return _response_for(request, klass, 'item_new', info_dict)
class NgModelFormMixin(NgFormBaseMixin): """ Add this NgModelFormMixin to every class derived from forms.Form, if you want to manage that form through an Angular controller. It adds attributes ng-model, and optionally ng-change, ng-class and ng-style to each of your input fields. If form validation fails, the ErrorDict is rewritten in a way, so that the Angular controller can access the error strings using the same key values as for its models. """ def __init__(self, *args, **kwargs): self.scope_prefix = kwargs.pop('scope_prefix', None) if hasattr(self, 'Meta') and hasattr(self.Meta, 'ng_models'): if not isinstance(self.Meta.ng_models, list): raise TypeError('Meta.ng_model is not of type list') ng_models = self.Meta.ng_models else: ng_models = None directives = {} for key in kwargs.keys(): if key.startswith('ng_'): fmtstr = kwargs.pop(key) directives[key.replace('_', '-')] = fmtstr if ng_models is None and 'ng-model' not in directives: directives['ng-model'] = '%(model)s' self.prefix = kwargs.get('prefix') if self.prefix and kwargs.get('data'): kwargs['data'] = dict((self.add_prefix(name), value) for name, value in kwargs['data'].get(self.prefix).items()) for name, field in self.base_fields.items(): identifier = self.add_prefix(name) ng = { 'name': name, 'identifier': identifier, 'model': self.scope_prefix and ('%s.%s' % (self.scope_prefix, identifier)) or identifier } if ng_models and name in ng_models: field.widget.attrs['ng-model'] = ng['model'] for key, fmtstr in directives.items(): field.widget.attrs[key] = fmtstr % ng super(NgModelFormMixin, self).__init__(*args, **kwargs) def full_clean(self): """ Rewrite the error dictionary, so that its keys correspond to the model fields. """ super(NgModelFormMixin, self).full_clean() if self._errors and self.prefix: self._errors = ErrorDict((self.add_prefix(name), value) for name, value in self._errors.items()) def get_initial_data(self): """ Return a dictionary specifying the defaults for this form. This dictionary shall be used to inject the initial values for an Angular controller using the directive 'ng-init={{thisform.get_initial_data|js|safe}}'. """ data = {} for name, field in self.fields.items(): if hasattr(field, 'widget') and 'ng-model' in field.widget.attrs: data[name] = self.initial and self.initial.get(name) or field.initial return data
def fork(request, klass, id): """Create a new item of given klass. @param request: request data @type request: Django request @param klass: item's class for lookup in correct database table @type klass: either Data, Task or Method @return: user login page, item's view page or this page again on failed form validation @rtype: Django response @raise Http404: if given klass is unexpected """ if not request.user.is_authenticated(): return HttpResponseRedirect(reverse('user_signin') + '?next=' + request.path) prev = klass.get_object(id) if not prev: raise Http404 if not prev.can_fork(request.user): return HttpResponseForbidden() prev.klass = klass.__name__ prev.name+=' (forked)' upload_limit = Preferences.objects.get(pk=1).max_data_size formfunc = eval(klass.__name__ + 'Form') if request.method == 'POST': form = formfunc(request.POST, request.FILES, request=request) # manual validation coz it's required for new, but not edited Data if not request.FILES and klass == Data: form.errors['file'] = ErrorDict({'': _('This field is required.')}).as_ul() # check whether file is too large if klass in (Data, Task) and 'file' in request.FILES: if len(request.FILES['file']) > upload_limit: form.errors['file'] = ErrorDict({'': _('File is too large! Must be smaller than %dMB!' % (upload_limit / MEGABYTE))}).as_ul() if form.is_valid(): new = form.save(commit=False) new.pub_date = datetime.datetime.now() try: new.slug = new.make_slug() except IntegrityError: # looks quirky... d = ErrorDict({'': _('The given name yields an already existing slug. Please try another name.')}) form.errors['name'] = d.as_ul() else: new.version = 1 new.is_current = True new.is_public = False new.user = request.user if not form.cleaned_data['keep_private']: new.is_public = True if klass == Data: new.file = request.FILES['file'] new.num_instances = -1 new.num_attributes = -1 new.save() # InMemoryUploadedFile returns file-like object whereas # zipfile/tarfile modules used in get_uncompressed() require # filename (prior to python 2.7), so we have to save it to # disk, then rename, then save object again. name_old = os.path.join(MEDIA_ROOT, new.file.name) uncompressed = ml2h5.data.get_uncompressed(name_old) if uncompressed: os.remove(name_old) name_old = uncompressed new.format = ml2h5.fileformat.get(name_old) name_new = os.path.join(DATAPATH, new.get_filename()) os.rename(name_old, os.path.join(MEDIA_ROOT, name_new)) new.file.name = name_new new.save() elif klass == Task: taskinfo = { 'train_idx': (form.cleaned_data['train_idx']), 'test_idx': (form.cleaned_data['test_idx']), 'input_variables': form.cleaned_data['input_variables'], 'output_variables': form.cleaned_data['output_variables'] } new.file = None if 'file' in request.FILES: new.file = request.FILES['file'] new.save() new.create_next_file(prev=None) else: new.save(taskinfo=taskinfo) new.license = FixedLicense.objects.get(pk=1) # fixed to CC-BY-SA new.save(taskinfo=taskinfo) elif klass == Method: #if 'score' in request.FILES: # new.score = request.FILES['score'] # new.score.name = new.get_scorename() new.license = FixedLicense.objects.get(pk=1) # fixed to CC-BY-SA new.save() elif klass == Challenge: new.license = FixedLicense.objects.get(pk=1) # fixed to CC-BY-SA new.save() new.task=form.cleaned_data['task'] new.save() else: raise Http404 return HttpResponseRedirect(new.get_absolute_slugurl()) else: form = formfunc(request=request, instance=prev) info_dict = { 'klass': klass.__name__, 'uuid': uuid.uuid4(), # for upload progress bar 'url_new': request.path, 'form': form, 'request': request, 'tagcloud': get_tag_clouds(request), 'section': 'repository', 'upload_limit': "%dMB" % (upload_limit / MEGABYTE) } return _response_for(request, klass, 'item_new', info_dict)