Thanks, Niphlod. Still learning, and asking questions is how I do it. I'll work on your suggestions from this and the other thread.

On 3/20/2012 5:10 PM, Niphlod wrote:
You are using validators in the wrong way, and also the forms in a twisted one.....maybe a little refresh reading the book is necessary....

1st of all....

Field('reportedby', 'string', db.auth_user, writable=False, readable=False, default=auth.user.username if auth.user else '')

you are trying to reference db.auth_user, but references are with the id field, not the username one .... If you want to insert in the field "reportedby" only the usernames present into the database, you must use a

requires=IS_IN_DB(db, 'auth_user.username')

2nd.... once the model is correct, if you try to insert the same ip in the table using the admin interface, you are presented with the error "value already in database or empty", that is correct.....
So, the model correct, let's get to the controller....

Assuming you want a single field (only the ip address) in a form, why the hell go for SQLFORM.factory ??


If you need SQLFORM.factory for - at the moment of writing - unknown reasons, the way it is supposed to work is:

def yourcontrollerfunction():
    form = SQLFORM.factory(Field('data', 'text', requires=IS_NOT_EMPTY()))

    if form.process(session=None).accepted:

        content = '192.168.0.1' #form.vars.data
        i = db.ips.validate_and_insert(ipaddress=content)
        if i.errors:
response.flash = UL([LI(a, ':', i.errors[a]) for a in i.errors])
        else:
            response.flash = content#'accepted'

    return dict(form=form)

Mind that you are exposing a text field, form.process(session=None) is actually only checking that the form will not be empty (the requires in the "data" field of the SQLFORM.factory). You then take the contents of the form (form.vars.data, in this particular case overridden by '192.168.0.1') and then doing the validation using the "validate_and_insert" api of the table "ips", that checks for the validators (in this case only the ones attached to "ipaddress" are used)...

NB: This is an overcomplicated way to do that.
form = SQLFORM(db.ips, fields=['ipaddress'])
will have done the job without all the hassle.

Niphlod

Il giorno martedì 20 marzo 2012 20:59:49 UTC+1, Larry Wapnitsky ha scritto:

    I'm having an issue (in my first real web2py application) whereby
    I'm unable to validate DB data via the DAL without creating a
    duplicate entry.


    I have the following code in my db.py:

    db.define_table('ips',
        Field('id', 'id'),
        Field('ipaddress','string', length=15, unique=True),
        Field('dateadded', 'datetime', writable=False, readable=False,
    default=request.now),
        Field('reportedby', 'string', db.auth_user,  writable=False,
    readable=False, default=auth.user.username if auth.user else ''),
        Field('updated', 'datetime', writable=False, readable=False,
    default=request.now),
        Field('attacknotes', 'text'),
        Field('b_or_w', 'string', length=1,
    widget=SQLFORM.widgets.radio.widget,
    requires=IS_IN_SET(['b','w']), default='b'),
        migrate=False)

    db.ips.ipaddress.requires = [IS_NOT_IN_DB(db, 'ips.ipaddress')]
    db.ips.ipaddress.requires.append(IS_IPV4())


    This is in my default.py:

    def form_from_factory():
        sample=''

        form = SQLFORM.factory(Field('data', 'text',
    requires=IS_NOT_EMPTY()))
        if form.process(session=None,
    onvalidation=validate_form).accepted:

            session.data = form.vars.data.split()

            x = '192.168.0.1'

            db.ips.reportedby.default="formtest"
            db.ips.dateadded.default=request.now
            db.ips.updated.default=request.now
            db.ips.ipaddress.requires = [IS_NOT_IN_DB(db, x)]

            session.flash = x#'accepted'
            redirect(URL('test'))
        return dict(form=form)

    I'm entering a list of IP addresses that get verified and, if
    valid, need to be input into the database.  With the test code you
    see above, I can create any number of entries that all have
    '192.168.0.1' even though I've specified the ipaddress in my DAL
    to be unique.

    HELP!

Reply via email to