Grid: New (create) form validation problem

74 views
Skip to first unread message

Jumbleoak

unread,
Feb 5, 2026, 2:01:07 PMFeb 5
to py4web
I am trying to validate a field. In models.py I have:

db.define_table(
    "weather",
    Field("temp"),
    etc.
)

db.weather.temp.requires = IS_EMPTY_OR(
IS_DECIMAL_IN_RANGE(-99, 99, dot=".", error_message='must be empty or a number from -99 to 99'))

The problem I have is that by introducing that validation the form displays '0.00' by default
whereas I want it to display nothing (and then by allowing that default of 0.00 to post it
results in 0.00 being posted to the underlying table - as expected).

In other words, I want the user to be able to enter a decimal from -99..0..99, and I want to validate any entry they do make, but I also want to be able to post NULL if they do not enter anything themselves.

(I confirm that the underlying mariadb table will accept NULL in the corresponding decimal field. I also confirm that I am new to py4web and python!)

Many thanks
Max

Massimo DiPierro

unread,
Feb 7, 2026, 8:13:34 PMFeb 7
to py4web
Can you please open a ticket about this. It looks like a bug in the IS_EMPTY_OR validator.

Jumbleoak

unread,
Feb 8, 2026, 8:22:31 AMFeb 8
to py4web
Hi,
I held back on the ticket because just to be more precise:

Used by itself, IS_DECIMAL_IN_RANGE() will insert a default value of '.00' in the form entry field. If that is left as the submitted value and it is is in range, as with minimum=-99, maximum=99, then 0 gets posted thru to the database. If the user deletes that default value, leaving the entry field blank, then the out of range error message is displayed. That is all as expected, except possibly for the initial insertion of '.00'.

If IS_EMPTY_OR(IS_DECIMAL_IN_RANGE()) is used, then a default value of '.00' is still inserted in the form entry field.  If that is left as the submitted value and it is is in range, as with minimum=-99, maximum=99, then 0 gets posted thru to the database. But, if the user deletes that default value, leaving the entry field blank, then None/null gets posted thru to the database. This is also all as expected, except possibly  for the initial insertion of '.00'.

I don't know if it is actually an issue that IS_DECIMAL_IN_RANGE() inserts a default value of '.00'. But if it is not, then my question boils down to: Is there any way to to start with a blank entry field, and on submission validate that the final entry is in [blank/None/null, -99..0..99]?

(Just so I don't waste anyone's time, I can now do this with a custom validator, but it isn't pretty)

Thank you.

Massimo DiPierro

unread,
Feb 8, 2026, 7:29:57 PMFeb 8
to py4web
I think the behavior should be:
1) IS_DECIMAL_IN_RANGE should prefill with 0 if 0 is in between range, else should use the minimum value
2) IS_EMPTY_OR(...) should never have a prefill value

I suspect anyway, that the prefill value comes from Field("name", "decimal", ..., default=0.0)
Have you tried Field("name", "decimal", ..., default=None)?

Jumbleoak

unread,
Feb 9, 2026, 10:12:14 AMFeb 9
to py4web
Hi,
Yes, I tried Field("name", "decimal", ..., default=None), with and without "decimal", with both IS_DECIMAL_IN_RANGE() and IS_EMPTY_OR(IS_DECIMAL_IN_RANGE()) and the prefill is '.00' in all cases.

So, if IS_EMPTY_OR() is supposed to overwrite or otherwise prevent the prefill from IS_DECIMAL_IN_RANGE(), then it does not appear to be doing that. On that basis I could open an issue.

Thank you.

Massimo DiPierro

unread,
Feb 16, 2026, 5:38:36 PMFeb 16
to py4web
I think this is fixed now. Can you please help me test it?

Jumbleoak

unread,
Feb 17, 2026, 6:22:37 AMFeb 17
to py4web
Hi,
I certainly can. I have downloaded validators.py, objects.py and __init__.py for the pydal folder and will repeat the tests I did.

Jumbleoak

unread,
Feb 19, 2026, 7:47:22 AM (12 days ago) Feb 19
to py4web
Hi
IS_EMPTY_OR(IS_DECIMAL_IN_RANGE()) works as expected:
- The prefill is blank.
- If no entry is made and the form is submitted, then None shows in the new row in the grid and null goes thru to the db.
- If an entry is made and deleted, then same as above.
- If an entry within range is made then that appears in grid and db as expected.
- This also works even if the range does not include 0, eg. min=9, max=99
- Setting default=x in Field() shows that value as the prefill.

On its own IS_DECIMAL_IN_RANGE() also works - as far as I'm concerned:
- The prefill is blank. *** But is this behaviour open to question? ***
- A blank is invalid on form submit.
- Setting default=x in Field() shows that value as the prefill.

Massimo DiPierro

unread,
Feb 21, 2026, 5:30:03 PM (10 days ago) Feb 21
to py4web
I think the prefill always came from the default value. The .00 was a wrong conversion from default=None. I think this is ok
Reply all
Reply to author
Forward
0 new messages