Discussion:
[FE-discuss] Writing a validator to look for cookie data
Matthew Wilson
2009-03-12 17:39:40 UTC
Permalink
I store fields from form submissions into a cookie, and then when a
user hits a form, I prepopulate the form with that data.

I want to write a validator that first tries to get values from the
query string, and if that is None, then the validator should check the
cookie.

Here is what I have:

class LookInCookie(FancyValidator):
"""
Retrieves something from the cookie. Depends on a state with an
attribute named 'simple_cookie'.
"""

def __init__(self, k, d=None):
"""
Return k from the cookie, or d if it isn't there.
"""
self.k, self.d = k, d

def to_python(self, value, state=None):

log.debug("Inside LookInCookie.to_python with locals: %s"
% locals())

if hasattr(state, 'simple_cookie') \
and state.simple_cookie.has_key(self.k):

return state.simple_cookie[self.k]

else:
return self.d
from turbogears.util import Bunch
s = Bunch(simple_cookie={'city':1})
v = Any(LookInCookie('city'), validators.Int())
v.to_python('99', s)
99
v.to_python('abc', s)
1

So far, so good! First, the Int validator runs, then when Int fails,
I get the value from the cookie s.

However, here's where things fall apart. When there is no value
passed in, nothing comes back out!
v.to_python('', s)
v.to_python(None, s)
How do I force validators to run even when the value is missing?

More generally, is there a better solution to what I'm trying to do?
--
Matthew Wilson
***@tplus1.com
http://tplus1.com
Ian Bicking
2009-03-12 18:18:51 UTC
Permalink
For something like this, I usually handle this stuff with unencoded
values. That is, I don't hit the validator at all when rendering the
form. I'd just get the defaults like:

if req.method == 'POST':
defaults = req.POST.mixed()
force_defaults = True
else:
defaults = {}
force_defaults = False
defaults.update(cgi.parse_qs(req.cookies.get('form_defaults', '')))
defaults.update(req.GET.mixed())
body = htmlfill.render(form, defaults, force_defaults=force_defaults)

If you want to use a validator, I'd use it on the line "defaults={}",
and replace that with something that grabs the encoded values from
some existing model, then runs "defaults =
schema.from_python(values)".
Post by Matthew Wilson
I store fields from form submissions into a cookie, and then when a
user hits a form, I prepopulate the form with that data.
I want to write a validator that first tries to get values from the
query string, and if that is None, then the validator should check the
cookie.
   """
   Retrieves something from the cookie.  Depends on a state with an
   attribute named 'simple_cookie'.
   """
       """
       Return k from the cookie, or d if it isn't there.
       """
       self.k, self.d = k, d
       log.debug("Inside LookInCookie.to_python with locals: %s"
           % locals())
       if hasattr(state, 'simple_cookie') \
           return state.simple_cookie[self.k]
           return self.d
from turbogears.util import Bunch
s = Bunch(simple_cookie={'city':1})
v = Any(LookInCookie('city'), validators.Int())
v.to_python('99', s)
99
v.to_python('abc', s)
1
So far, so good!  First, the Int validator runs, then when Int fails,
I get the value from the cookie s.
However, here's where things fall apart.  When there is no value
passed in, nothing comes back out!
v.to_python('', s)
v.to_python(None, s)
How do I force validators to run even when the value is missing?
More generally, is there a better solution to what I'm trying to do?
--
Matthew Wilson
http://tplus1.com
------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
FormEncode-discuss mailing list
https://lists.sourceforge.net/lists/listinfo/formencode-discuss
--
Ian Bicking | http://blog.ianbicking.org
Matthew Wilson
2009-03-13 01:58:33 UTC
Permalink
Thanks for the tip.

Any idea why Any() doesn't seem to run in my code when no value exists?

Matt
Post by Ian Bicking
For something like this, I usually handle this stuff with unencoded
values.  That is, I don't hit the validator at all when rendering the
   defaults = req.POST.mixed()
   force_defaults = True
   defaults = {}
   force_defaults = False
defaults.update(cgi.parse_qs(req.cookies.get('form_defaults', '')))
defaults.update(req.GET.mixed())
body = htmlfill.render(form, defaults, force_defaults=force_defaults)
If you want to use a validator, I'd use it on the line "defaults={}",
and replace that with something that grabs the encoded values from
some existing model, then runs "defaults =
schema.from_python(values)".
Post by Matthew Wilson
I store fields from form submissions into a cookie, and then when a
user hits a form, I prepopulate the form with that data.
I want to write a validator that first tries to get values from the
query string, and if that is None, then the validator should check the
cookie.
   """
   Retrieves something from the cookie.  Depends on a state with an
   attribute named 'simple_cookie'.
   """
       """
       Return k from the cookie, or d if it isn't there.
       """
       self.k, self.d = k, d
       log.debug("Inside LookInCookie.to_python with locals: %s"
           % locals())
       if hasattr(state, 'simple_cookie') \
           return state.simple_cookie[self.k]
           return self.d
from turbogears.util import Bunch
s = Bunch(simple_cookie={'city':1})
v = Any(LookInCookie('city'), validators.Int())
v.to_python('99', s)
99
v.to_python('abc', s)
1
So far, so good!  First, the Int validator runs, then when Int fails,
I get the value from the cookie s.
However, here's where things fall apart.  When there is no value
passed in, nothing comes back out!
v.to_python('', s)
v.to_python(None, s)
How do I force validators to run even when the value is missing?
More generally, is there a better solution to what I'm trying to do?
--
Matthew Wilson
http://tplus1.com
------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
FormEncode-discuss mailing list
https://lists.sourceforge.net/lists/listinfo/formencode-discuss
--
Ian Bicking  |  http://blog.ianbicking.org
--
Matthew Wilson
***@tplus1.com
http://tplus1.com
Ian Bicking
2009-03-13 15:58:03 UTC
Permalink
Well, first be careful, Any runs the last validator in the list first.
Also, hm... Any reads the not_empty value of its sub-validators and
uses that, and if any of the validators accept empty values then it
shortcuts the process. Hrm. I think All has been revised to be a
little more sensible (the is_empty method on All always returns
false). Yeah... okay, I changed that in trunk so Any and All work the
same.
Post by Matthew Wilson
Thanks for the tip.
Any idea why Any() doesn't seem to run in my code when no value exists?
Matt
Post by Ian Bicking
For something like this, I usually handle this stuff with unencoded
values.  That is, I don't hit the validator at all when rendering the
   defaults = req.POST.mixed()
   force_defaults = True
   defaults = {}
   force_defaults = False
defaults.update(cgi.parse_qs(req.cookies.get('form_defaults', '')))
defaults.update(req.GET.mixed())
body = htmlfill.render(form, defaults, force_defaults=force_defaults)
If you want to use a validator, I'd use it on the line "defaults={}",
and replace that with something that grabs the encoded values from
some existing model, then runs "defaults =
schema.from_python(values)".
Post by Matthew Wilson
I store fields from form submissions into a cookie, and then when a
user hits a form, I prepopulate the form with that data.
I want to write a validator that first tries to get values from the
query string, and if that is None, then the validator should check the
cookie.
   """
   Retrieves something from the cookie.  Depends on a state with an
   attribute named 'simple_cookie'.
   """
       """
       Return k from the cookie, or d if it isn't there.
       """
       self.k, self.d = k, d
       log.debug("Inside LookInCookie.to_python with locals: %s"
           % locals())
       if hasattr(state, 'simple_cookie') \
           return state.simple_cookie[self.k]
           return self.d
from turbogears.util import Bunch
s = Bunch(simple_cookie={'city':1})
v = Any(LookInCookie('city'), validators.Int())
v.to_python('99', s)
99
v.to_python('abc', s)
1
So far, so good!  First, the Int validator runs, then when Int fails,
I get the value from the cookie s.
However, here's where things fall apart.  When there is no value
passed in, nothing comes back out!
v.to_python('', s)
v.to_python(None, s)
How do I force validators to run even when the value is missing?
More generally, is there a better solution to what I'm trying to do?
--
Matthew Wilson
http://tplus1.com
------------------------------------------------------------------------------
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
_______________________________________________
FormEncode-discuss mailing list
https://lists.sourceforge.net/lists/listinfo/formencode-discuss
--
Ian Bicking  |  http://blog.ianbicking.org
--
Matthew Wilson
http://tplus1.com
--
Ian Bicking | http://blog.ianbicking.org
Loading...