On Saturday 26 May 2007 14:57:36 aspineux wrote:
> On 26 mai, 15:35, Jorge Godoy <[EMAIL PROTECTED]> wrote:
>
> Hi Jorge, thanks for your valuable answer.
Hi aspineux. You're welcome.
> I rewrote my sample using a chained validator doing all the job of
> user creation.
> I put it at the end, but I didn't test it for real !
Sorry for taking too long to answer. I'm traveling abroad in a few hours and
I'm putting my things together... I'll be out for 15 days -- so, if there's
somebody here from Buffalo, I'll be at the Adam's Mark, I'll have some free
time there and having someone to help with sightseeing and the like would be
great... -- on business.
Did you test it by now?
> 1. I put most of the code from the controller in the validator.
You have to put enough code to validate what you want. No more and no
less :-) I believe that the worst part for this specific validator is the
database connection.
> 2. The validator extend the field_dict it got for validation with some
> result of the processing
Theoretically a validator should just make simple tasks and not complex
ones... I mean, you should change very little from the data unless it is
expected -- e.g. to convert the string got from the web to some specific
python type and vice-versa -- by the user. This is very important to avoid
side effects and allow for cascading validators.
If something fails, the validator raises and Invalid exception with the
correct message.
> 3. These new values can then be used by the controller notice the
> user.
:-)
> (2) is the sensitive part. I know it works, but I don't know if I can
> do that.
I'd avoid messing too much with data on a validator. It is only doing what
its name says: validating your data (it can also do the extra step of
converting it to Python or from Python to a string to be shown at the web) .
> > What I see is that this would bring more harm than good and would add
> > extra code that needed to be maintained in TG.
>
> This is the price for any new feature :-)
But new features should be very carefully thought so that this is an
acceptable price. Since what you proposed was already doable with existing
code, my opinion is that it isn't worth it.
> I don't understand how @validate and @error_handler can do their job.
I can't explain it now, unfortunately, but if you're still stuck with it in
15 - 20 days, send another message asking for that to the list... I dunno if
I'll have a notebook there soon or if there's any kind of Internet connection
at the hotel.
> To replay the controller that display the form, @error_handler should
> have a copy of the previous request, to redo exactly the same.
tg_errors contains all fields that weren't validated correctly.
**kwargs (my chosen name) has all the input values and fields that got to the
controller.
> Second after the replay of the controller, @error_handler should
> modify the returned data to enforce the one the user filled in in the
> previous screen !
If you modify the data, it is not what the user entered anymore. So, you
can't change anything. :-)
> Can you clarify ? If you know :-)
I can't explain how @validate and @error_handler work now. You can try
reading the code a bit more, waiting for someone else to answer or ask again
in a few days when I come back from the US / get access to some network there
where I can read personal email.
> I looked the @validate and @error_handler code but no easy to
> understand ....
> This will require more than a weekend :-)
:-) Start simple. Write your validator. Use it. Then use already made
validators. Create a simple form and make it fail. See what happens.
Inspect all variables and code. Use debug (from logging module) to see
things.
You'll learn a lot in a few hours and I still believe that you could get that
in two or three days.
> Anyway if I get lots of support from people :-) ... maybe
:-) Who knows? If it gets generic enough to be useful for more people, then
you have more chances that they will help you.
> Here is my code.
> Is it what you had in mind ?
I hadn't thought of any implementation, so the real answer is "no". :-) But I
am not saying it is incorrect.
> class NewUserValidation(formencode.FormValidator):
>
> def validate_python(self, field_dict, state):
> if field_dict['password1']!=field_dict['password2']:
> raise turbogears.validators.Invalid('Passwords dont
> match', field_dict, state, error_dict={'password2': 'Password dont
> match' })
This is not what I had on my mind. For this there's already a validator so
code reusing is mandatory on my book. ;-) If you don't want to chain
validators, you can instantiate the existing one here, but it isn't as good
as using what is available.
> newuser=model.User(user_name=user_name, password=password)
> session.save(newuser)
> try:
> session.flush()
> except:
> raise turbogears.validators.Invalid('Username already in
> use', field_dict, state, error_dict={'user_name': 'choose another
> username' })
This is bad practice: you're catching all exceptions and not just one specific
exception or tuple of exceptions. You should never do that because it might
hide other problems.
For example, the user might not exist but you might have database connectivity
problems, or you might have a wrong syntax or ... and you will never know
what has triggered the Invalid exception.
> # Extend field_dict with interesting results
>
> field_dict['user_id']=newuser.user_id
Do you really need to insert the user on the validator? This looks like
controller code to me. The validator would do a SELECT-equivalent and check,
at most. Validators should not have any side effect, specially not change
the database by themselves...
> class FormNewUser(widgets.TableForm):
> fields = [
> widgets.TextField('user_name', label='User login',
> validator=validators.String(not_empty=True)),
> widgets.PasswordField('password', label="Password" ,
> validator=validators.NotEmpty ()) ,
> widgets.PasswordField('password2', label="Password (Repeat)" ,
> validator=validators.NotEmpty()) ,
> ]
> validator = validators.Schema(
> chained_validators = [NewUserValidation()]
> )
> submit_text = "Create User"
You already know about the existence of chained validators. So you could use
it to check if both passwords supplied are the same instead of coding that on
your own controller.
> @turbogears.expose()
> @validate(form=new_user_form)
> @error_handler(index)
> def user_create(self, user_id, **kwargs):
>
> turbogears.flash("User successfuly added, user_id=!" % user_id)
> raise turbogears.redirect('show_user', dict(user_id=user_id))
I'd create the user here. Not on the validator.
--
Jorge Godoy <[EMAIL PROTECTED]>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---