Hi David,

On Jan 24, 8:39 am, David Kamenetz <kamene...@yahoo.ca> wrote:
> However, if the user only enters/changes, say, the txt field on the
> form I only POST the txt field to the server. I don't send all the
> fields. My POST only has data for txt. If I use the code above on an
> existing entity, it will erase the title property (formitem.title).
>
> Is there an elegant way to write only the txt element to the txt
> property?

As far as I know, you can't write only one property when replacing an
existing entity, but maybe there's something that can be done at the
lowest levels just before going to the protocol buffer. (See
datastore.py and datastore_pb.py in the SDK where entity dicts are
being passed.)

I use POSTs to create new entities and PUTs to modify existing ones or
store a new entity in a known url.  With the PUTs, if there's an
existing entity, you need to read it in and then selectively modify
key/values depending on what's been passed from your form.

So creating new entities through POST is simple.  Just set whatever
property you want to set on model initialization, and all others are
not stored.

You can automate the whole process by creating a Model you'll inherit
from (I call mine SerializableModel), and create a method that
iterates through all model properties, calls request.get() on them,
and if the get isn't None (i.e., there's a value passed in from your
form), you add that key/value to your entity dict.  You later pass the
entity dict as an initializer into your Model constructor.

For example:

def get_entity_dict(model_class, get_func):
    entity_dict = {}
    for prop_name, prop_class in model_class.properties().iteritems():
        value = get_func(prop_name)
        if value:
              entity_dict[prop_name] = model_class.deserialize
(prop_class, value)
    return entity_dict

So in the above, get_func is set to:

get_func = lambda x : some_handler.request.get(x, default_value=None)

We only set key/value pairs in entity_dict for properties that are set
in form.

The model_class.deserialize() is a routine that takes strings from the
form and converts them into appropriate datastore objects.

So in your handler you'd have something like this in simplified form:

def post(self):
    get_func = lambda x : some_handler.request.get(x,
default_value=None)
    props = get_entity_dict(MyModel, get_func)
    obj = MyModel(**props)
    obj.put()

For the PUT case, you read the entity first, set the entity_dict to
the current entity values, and then do the above.

I might open source the model system I've created that does all this
stuff.

-Bill



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To post to this group, send email to google-appengine@googlegroups.com
To unsubscribe from this group, send email to 
google-appengine+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to