I don't know if this will help but I've built a custom property for
dealing with basic dict items. It's based on StringListProperty, so
you still have some indexing for searching on keys, or "key:value"
pairs.
The code has not been tested much yet...
class DictListProperty(db.StringListProperty):
def __init__(self, *args, **kwds):
#cache reads so we only process list once
self._cache = None
super(DictListProperty, self).__init__(*args, **kwds)
def get_value_for_datastore(self, model_instance):
value = super(DictListProperty,
self).get_value_for_datastore(model_instance)
if value is None:
return None
else:
#convert dict to list of key:value
l=[]
for k, v in value.items():
#expand any lists out (for tag lists etc)
if isinstance(v,list):
l.append(k)#add empty key with no value
so we know this is a list
for i in v:
l.append(k+":"+str(i))
else:
l.append(k+":"+str(v))
return self.data_type(l)
def validate(self, value):
return value
def make_value_from_datastore(self, value):
if self._cache is None:
if value is None:
return None
elif isinstance(value, list):
self._cache = {}
#split list of key:values back into dict
for v in value:
s=v.split(":",1)
if len(s)==1 and
self._cache.has_key(s[0]): #special case for
single item list
self._cache[s[0]] =
list(self._cache[s[0]])
elif len(s)==1: #special case for empty
list
self._cache[s[0]] = []
elif self._cache.has_key(s[0]): #add to
list
self._cache[s[0]] =
list(self._cache[s[0]])
self._cache[s[0]].append(s[1])
else:
self._cache[s[0]]=s[1]
return self._cache
else:
return None
else:
return self._cache
#Tests..
class TestModel(db.Model):
d = DictListProperty()
#Main Test
t = TestModel()
t.d = {"a":1,"b":"2test","c":"3:test'here'withsemicolon
+junk&in,string"} #basic key:value structure, non-strings saved as
string
t.d["list"]=[0,1,2,3] #lists are also supported, expanded and stored
as d,d:0,d:1,d:2 etc. so can be indexed.
t.d["empty"]=[] #empty list will return as empty list, stored as just
"key"
t.put()
t = TestModel.get(p.key())
#t = Test.all().filter("d = ","b:2test").get() #for equality you need
to combine full "key:value" as string
#t = Test.all().filter("d = ","list:2").get() #lists are expanded for
indexing
#t = Test.all().filter("d >= ","c:").get() #inequalities can be user
to to test for just keys.
self.response.out.write(t.d) #returns a dict
self.response.out.write(t.d["list"]) #lists are re-combined
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Google App Engine" 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/google-appengine?hl=en
-~----------~----~----~----~------~----~------~--~---