Providing "unmanaged", read-only model instance in GAE
Does anyone know of a clever way in Google App Engine to return an instance of a Model instance that only provides some of the original properties and does not allow the instance to be saved back to the datastore?
I am not looking for ways to actually apply these rules, obviously it would still be possible to modify the instance by digging through it __dict__
, etc. I just want to avoid accidentally affecting / modifying the data.
My initial thought was to do this (I want to do this for the public version of the model User
):
class PublicUser(db.Model):
display_name = db.StringProperty()
@classmethod
def kind(cls):
return 'User'
def put(self):
raise SomeError()
Unfortunately, GAE maps the view to a class first, so if I do PublicUser.get_by_id(1)
, I actually return an instance User
, not an instance PublicUser
.
Also, the idea is that it should at least be an instance Model
so that I can pipe it to code that doesn't know that it is a "dumbfounded" version. Ultimately I want to do this so that I can use my generic read-only data expose functions so that they only display public information about the user.
Update
I went with the icio solution. Here's the code I wrote to copy properties from an instance User
to an instance PublicUser
:
class User(db.Model):
# ...
# code
# ...
def as_public(self):
"""Returns a PublicUser version of this object.
"""
props = self.properties()
pu = PublicUser()
for prop in pu.properties().values():
# Only copy properties that exist for both the PublicUser model and
# the User model.
if prop.name in props:
# This line of code sets the property of the PublicUser
# instance to the value of the same property on the User
# instance.
prop.__set__(pu, props[prop.name].__get__(self, type(self)))
return pu
Please comment if this is not the best way to do it.
a source to share
Failed to create a method in the class User
that creates an object ReadOnlyUser
and copies the values of the member variables as needed? Your call will look like User.get_by_id(1).readonly()
using a method readonly
defined like this:
class User(db.Model):
def readonly(self):
return ReadOnlyUser(self.name, self.id);
Or you could if your class User
extended another class with methods to do this automatically based on some static vars display properties to copy or something.
PS I am not coding in Python
a source to share