id fields do not get any validators by default, and if they did, it
certainly would not be an IS_IN_DB validator (if anything, it would be
IS_NOT_IN_DB, as id values must be unique). Can we see your table
definition?
Is it possible the problem is instead with a reference field, which by
default would have an IS_IN_DB validator and would therefore be required
for an insert?
Anthony
On Monday, May 8, 2017 at 6:28:50 PM UTC-4, Joe Barnhart wrote:
>
> So I'm using "validate_and_insert" to, well, validate and insert some
> values. Its a simple function and easily understood:
>
> def validate_and_insert(self, **fields):
> response, new_fields = self._validate_fields(fields)
> if not response.errors:
> response.id = self.insert(**new_fields)
> return response
>
> It relies on "_validate" to check the validators:
>
> def _validate_fields(self, fields, defattr='default'):
> response = Row()
> response.id, response.errors = None, Row()
> new_fields = copy.copy(fields)
> for fieldname in self.fields:
> default = getattr(self[fieldname], defattr)
> if callable(default):
> default = default()
> raw_value = fields.get(fieldname, default)
> value, error = self[fieldname].validate(raw_value)
> if error:
> response.errors[fieldname] = "%s" % error
> elif value is not None:
> new_fields[fieldname] = value
> return response, new_fields
>
> And here lies the problem. The field "id" was NOT provided in the
> "fields" argument since we are inserting values, i.e. we don't have an id
> yet. But in the loop "for fieldname in self.fields" we are looping through
> ALL of the fields in the able, including "id". It's clear the reason is to
> process the "default" values for each field -- a good idea. What's NOT a
> good idea is processing the validator for "id" which defines "id" can't be
> None.
>
> The default validator for "id" is an IS_IN_DB validator. It fails when
> the argument (value) is "None" in the following fragment:
>
> else:
> if field.type in ('id', 'integer'):
> if isinstance(value, (int, long)) or value.isdigit():
> value = int(value)
>
> The failure happens on if isinstance(value, (int, long)) or
> value.isdigit(): The value "None" fails the first test, but "or"
> requires both arguments be evaluated if the first test fails, so it goes on
> to the second test, which gives an exception.
>
> I'm not sure how this ever worked, but I'm sure it did at one point.
> Maybe there was a regression. This was done in web2py 2.14.6-stable.
>
> -- Joe
>
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.