Now my Flex and Python Test project has the basic CRUD operations. It can create, retrieve, update and delete objects.
This is how the operations are implemented on the server:
class Project(db.Model):
code = db.IntegerProperty()
name = db.StringProperty()
created_at = db.DateTimeProperty(auto_now_add=True)
modified_at = db.DateTimeProperty(auto_now=True)
class ProjectService:
def get(self, code):
logging.debug('get %s' % (code))
project = Project.gql("WHERE code = :1", code).get()
return project
def insert(self, project):
logging.debug('insert %s' % (project))
new_project = Project()
new_project.code = int(project.code)
new_project.name = project.name
new_project.put()
return new_project
def update(self, project):
logging.debug('udpate %s' % (project))
existing_project = Project.get(project._key)
existing_project.name = project.name
existing_project.put()
return Project.get(project._key)
def save(self, project):
logging.debug('save %s' % (project))
if hasattr(project, '_key') and project._key != None:
return self.update(project)
else:
return self.insert(project)
def delete(self, project):
logging.debug('delete %s' % (project))
existing_project = Project.get(project._key)
existing_project.delete()
def get_all(self):
logging.debug('get_all')
return Project.all().fetch(1000)
In my project, these operations are used in a Flex form and in a Python command-line application. All the source code is published in github. Feedback is welcome.
Edit: This is an ongoing project that has advanced quite a lot since this article. Browse my blog if you’re interested in learning about the progress of this example.
Hi Fernando,
I just responded under your App Engine post, but here it is anyway:
OK, being the ‘Rails Refugee’ that I am, I appreciate the REST cause as much as anyone. As DHH implemented it, you should only need 7 actions for your controller (for 95% of cases): INDEX, SHOW, EDIT, UPDATE, NEW, CREATE, DESTROY.
Because of how Python and Django work, I am able to get all that in only 3 (SHOW, EDIT, DELETE), and my urls.py file lays it out:
—–
(r’^blog/item/(\d+)/$’, ‘item.show’), # one Item
(r’^blog/items/([-\w]+)/$’, ‘item.show’), # Items matching Tag string
(r’^blog/edit/$’, ‘item.edit’), # new Item
(r’^blog/edit/(\d+)/$’, ‘item.edit’), # edit Item
(r’^blog/delete/(\d+)/$’, ‘item.delete’), # delete
(r’^blog/items/$’, ‘item.show’), # all Items
—–
The reason is that you don’t have to do the ‘new’ thing; you just edit a non-existent Item, and a form is created which sends the input back to the ‘view’ (controller). Id assignment happens after the instance is ‘put’.
Think about it: ‘index’ and ’show’ differ only in quantity; ‘new’, ‘create’, ‘edit’, and ‘update’ are all different aspects of the same thing. Only ‘delete’ is non-polymorphous.
So, right now, I’m working to implement ALL actions for my app with just these three functions for each Model I have defined, by using arguments passed in to switch operations as needed.
I know I haven’t said the word ‘CRUD’ yet, but I suppose you could call my idea ‘RUD’, because ‘create’ and ‘update’ are really two faces of the same action. Kind of like ‘zero’ in math, you just ‘update’ a non-existent entity when you ‘create’!
My learning app is here:
http://archi-checker.appspot.com
Comment by G-man — July 22, 2008 @ 1:00 am