diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py
index 409ad9dc..11206dbd 100644
--- a/gluon/sqlhtml.py
+++ b/gluon/sqlhtml.py
@@ -1535,8 +1535,20 @@ class SQLFORM(FORM):
if not value is None:
fields[fieldname] = safe_int(value)
elif field.type.startswith('reference'):
- if not value is None and isinstance(self.table, Table) and not keyed:
- fields[fieldname] = safe_int(value)
+ ## Avoid "constraint violation" exception when you have a
+ ## optional reference field without the dropdown in form. I.e.,
+ ## a field with code to be typed, in a data-entry form.
+ ##
+ ## When your reference field doesn't have IS_EMPTY_OR()
+ ## validator, "value" will come here as a string. So,
+ ## safe_int() will return 0. In this case, insert will raise
+ ## the constraint violation because there's no id=0 in
+ ## referenced table.
+ if isinstance(self.table, Table) and not keyed:
+ if not value:
+ fields[fieldname] = None
+ else:
+ fields[fieldname] = safe_int(value)
elif field.type == 'double':
if not value is None:
fields[fieldname] = safe_float(value)