On Wed, Jul 27, 2011 at 1:02 PM, Eduardo Miguez
<[email protected]> wrote:
> Hi guys, I'm new to this Pyramid world (as a matter of fact I'm new to
> web development world) so I have a "best practice" question:
>  Let's say I have this "users" model where I can store and retrieve
> user information such as name, social security id, address and the
> likes.
> If I want somebody to edit some of this information for a particular
> user I have to query the database and present the information through
> a view. If somebody updates some of that information it seems i have
> to create another view to receive the data, get the updated user id
> from the request, query the db again to populate an ORM object where
> to apply the changes submitted and update the instance. Looks to me
> that for every action I need to write two views and perform the same
> query twice (I would imagine that I could send the user instance in
> the view but I don't know how). Is that right?

There's a natural sequence in form processing, which you'll get
familiar with if you practice with the form tutorials. The sequence is
forced by the stateless and string-based nature of HTTP and HTML, so
you can't avoid it except by making a client-side
(Javascript/Flash/Java) application.

In the first request, the user GETs the page containing the form. It's
easiest to encode the record ID in the URL:  /records/1234/edit . That
way it's separate from the POST and GET variables. You fetch the model
object (ORMClass.get(1234)) and plug the current values into the form.
Or if it's a new record you set the form fields to their blank/default
values. I like to use the same template for both adding and updating,
so I include a boolean flag 'is_adding' in my template variables.

The user fills out the form and POSTs it back to you. You can have it
post back to the same view or a different view, as you wish. The
Pylons default was to post it to a different view, but many Pyramid
users post to the same view. The latter is simpler in my opinion. So
you'd structure the view as Malthe suggested:

    id_ = self.request.matchdict["id"]
    obj = model.ORMClass.get(id)
    abort 400 if ID is invalid, or 404 if the object does not exist
    if self.request.method == "POST":
        validate input
        if input is valid:
            update object and commit
            optionally set a flash message using
session.flash("successfully updated record")
            redirect to the record's display page
        else:
            # input is not valid
            set error messages in form
            set form variables to user input
    else:
        # The user has not seen the form yet, or is reloading the form page
        set form variables to the object's current state
    render form

So the object is fetched twice, but in two different requests. You
can't share an object instance between requests, at least not without
fancy caching or storing it in the session, but those add too much
complexity.  There's little overhead in fetching a single record by
its primary key, and the overhead is worth it if it's important to
modify this record.

You can't send an object to the browser. Even if you could, you'd have
to validate the entire object when you get it back because the user
could have done anything to it, including returning a broken or hacked
or fake object. The only exception is if you're writing a client-side
application (Javascript, Flash, or Java); then it could make an AJAX
request for a JSON representation of the object, and submit the
updates via JSON. But in that case your server-side application would
be a web service, and you wouldn't be sending forms from the server
(probably).

-- 
Mike Orr <[email protected]>

-- 
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" 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/pylons-discuss?hl=en.

Reply via email to