I'm trying to implement something like Rails dynamic-finders in Python (for webapp/GAE). The dynamic finders work like this:
The Person class has a method called "find_by_name" that receives the name and returns the result of the query:
@classmethod
def find_by_name(cls, name):
return Person.gql("WHERE name = :1", name).get()
Instead of having to write a method like that for each attribute, I'd like to have something like Ruby's method_missing that allows me to do it.
So far I've seen these 2 blog posts: http://blog.iffy.us/?p=43 and http://www.whatspop.com/blog/2008/08/method-missing-in-python.cfm but I'd like to hear what's the "most appropiate" way of doing it.
There's really no need to use GQL here - it just complicates matters. Here's a simple implementation:
class FindableModel(db.Model):
def __getattr__(self, name):
if not name.startswith("find_by_"):
raise AttributeError(name)
field = name[len("find_by_"):]
return lambda value: self.all().filter(field, value)
Note that it returns a Query object, which you can call .get(), .fetch() etc on; this is more versatile, but if you want you can of course make it just return a single entity.
You could use a 'find_by' method and keywords, like Django does:
class Person (object):
def find_by(self, *kw):
qspec = ' AND '.join('%s=%s' % kv for kv in kw.items())
return self.gql('WHERE ' + qspec)
person.find_by(name='Robot')
person.find_by(name='Robot', age='2')
Down this road you may end up designing your own query syntax. Take a look at what Django does...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With