Models are responsible for persisting data and containing business logic. Models are direct interfaces to Google App Engine’s Datastore. It’s recommended that you encapsulate as much of your business and workflow logic within your models (or a separate service layer) and not your controllers. This enables you to use your models from multiple controllers, task queues, etc without the worry of doing something wrong with your data or repeating yourself. Models can be heavily extended via Behaviors which allow you to encapsulate common model functionality to be re-used across models.
An example model to manage posts might look like this:
from ferris import BasicModel, ndb from ferris.behaviors import searchable class Post(BasicModel): class Meta: behaviors = (searchable.Searchable,) search_index = ('global',) title = ndb.StringProperty() idk = ndb.BlobProperty() content = ndb.TextProperty()
Models are named with singular nouns (for example: Page, User, Image, Bear, etc.). Breaking convention is okay but scaffolding will not work properly without some help.
Each model class should be in its own file under /app/models and the name of the file should be the underscored class name. For example, to create a model to represent furry bears, name the file /app/models/furry_bear.py. Inside the file, define a class named FurryBear.
The Model class is built directly on top of App Engine’s google.appengine.ext.ndb module. You may use any regular ndb.Model class with Ferris. Documentation on propeties, querying, etc. can be found here.
Base class that augments ndb Models by adding easier find methods and callbacks.
Ferris provides two simple query shortcuts but it’s unlikely you’ll ever use these directly. Instead, you’ll use the automatic methods described in the next section.
Generates an ndb.Query with filters generated from the keyword arguments.
is the same as:
User.query().filter(User.first_name == 'Jon', User.role == 'Admin')
Similar to find_all_by_properties, but returns either None or a single ndb.Model instance.
The Model class automatically generates a find_by_[property] and a find_all_by_[property] classmethod for each property in your model. These are shortcuts to the above methods.
class Show(Model): title = ndb.StringProperty() author = ndb.StringProperty() Show.find_all_by_title("The End of Time") Show.find_all_by_author("Russell T Davies")
The Model class also provides aliases for the callback methods. You can override these methods in your Model and they will automatically be called after their respective action.
Called before an item is saved.
|Parameters:||self – refers to the item that is about to be saved|
|Note:||self.key is invalid if the current item has never been saved|
Called after an item has been saved.
Called after an item is retrieved.
|Parameters:||key – Is the key of the item that is to be retrieved.|
Called after an item has been retrieved.
Called before an item is deleted.
|Parameters:||key – is the key of the item that is about to be deleted. It is okay to get() this key to interogate the properties of the item.|
Called after an item is deleted.
|Parameters:||key – is the key of the item that was deleted. It is not possible to call get() on this key.|
These methods are useful for replicating database triggers, enforcing application logic, validation, search indexing, and more.
The BasicModel adds automatic access fields. These are useful for a variety of situations where you need to track who created and updated an entity and when.
Adds the common properties created, created_by, modified, and modified_by to Model
Stores the created time of an item as a datetime (UTC)
Stores the modified time of an item as a datetime (UTC)
Stores the user (a google.appengine.api.users.User) who created an item.
Stores the user (a google.appengine.api.users.User) who modified an item.