One option is to use an "onvalidation" function with your
form: http://web2py.com/books/default/chapter/29/7#onvalidation. In your
onvalidation function, you can re-use the field's compute function by
calling it with form.vars as its argument:
def my_onvalidation(form):
combinada = db.combinado.combinada.compute(form.vars)
[check if combinada is already in db, and if so, add error to
form.errors.primero and/or form.errors.segundo]
The above is a general solution. In your case, since you are just
concatenating two fields, it is sufficient to confirm that the combination
of the two fields is unique, which you can do by setting an appropriately
defined IS_NOT_IN_DB validator on one of the two fields -- here is an
example of how to do that: http://stackoverflow.com/a/8055987/440323.
Anthony
On Monday, February 20, 2012 12:44:03 PM UTC-5, Alan Etkin wrote:
>
> I want to define a table that has a compound field which concatenates
> data from two different field values on form submission. In addition,
> I would like to check the database on validation to make sure that the
> current record is the only to have that "combinada" field value. The
> unique argument restriction grants the redundancy is not allowed, but
> when duplicated values are sent, the model does not catch database
> integrity errors and therefore an exception is raised, at least that
> is what I assume so far. How could I catch the db exception at
> validation instead of having to handle an adapter related error (which
> in turn will probably work only for the current database adapter)?
>
> The prototype is as follows (using the default sqlite uri).
>
> Model:
>
> db.define_table("combinada", Field("combinado",
> requires=IS_NOT_EMPTY(), compute=lambda row: row.primero+row.segundo,
> unique=True, writable=False), Field("primero",
> requires=IS_NOT_EMPTY()), Field("segundo", requires=IS_NOT_EMPTY()))
>
> Here is the error traceback stored by web2py:
>
> Traceback (most recent call last):
> File "/home/alan/web2py/web2py-hg/gluon/restricted.py", line 204, in
> restricted
> exec ccode in environment
> File "/home/alan/web2py/web2py-hg/applications/compute/controllers/
> default.py", line 73, in <module>
> File "/home/alan/web2py/web2py-hg/gluon/globals.py", line 172, in
> <lambda>
> self._caller = lambda f: f()
> File "/home/alan/web2py/web2py-hg/applications/compute/controllers/
> default.py", line 18, in index
> form = crud.create(db.combinada)
> File "/home/alan/web2py/web2py-hg/gluon/tools.py", line 3168, in
> create
> formname=formname,
> File "/home/alan/web2py/web2py-hg/gluon/tools.py", line 3111, in
> update
> detect_record_change = self.settings.detect_record_change):
> File "/home/alan/web2py/web2py-hg/gluon/sqlhtml.py", line 1273, in
> accepts
> self.vars.id = self.table.insert(**fields)
> File "/home/alan/web2py/web2py-hg/gluon/dal.py", line 6634, in
> insert
> return self._db._adapter.insert(self,self._listify(fields))
> File "/home/alan/web2py/web2py-hg/gluon/dal.py", line 934, in insert
> raise e
> IntegrityError: column combinado is not unique