-
-
Notifications
You must be signed in to change notification settings - Fork 29
Models
A model is the reflection of a data store table. It allows you to manipulate data in an object-oriented, language-specific, pythonic way.
Each model created with remodel inherits remodel.models.Model
.
Model names should be written in CamelCase (e.g.: AwfullyLongName
). Corresponding table names are generated by pluralizing the underscore_case name of the model (e.g.: awfully_long_names
).
These methods are actually instance methods, so they are available only on instances of models.
Method name | Example usage | Description |
---|---|---|
save() |
obj.save() |
Saves the object to the database. NOTE: It does not save related objects! |
update(**kwargs) |
obj.update(field1=value1, field2=value2) |
Updates the object by adding kwargs field-value pairs to the object and saving the object to the database. |
delete() |
obj.delete() |
Removes the object from the database and attempts to remove any references to it contained by other objects. NOTE: It does not remove related objects! |
obj[field] = value |
Adds field with value to the object. |
|
obj[field] |
Retrieves the value of field . |
|
get(field[, default]) |
obj.get(field) or obj.get(field, default_value)
|
Retrieves the value of field , or default , if field is not set on the object. If no default is given, it is assumed to be None . This method never raises a KeyError . |
del obj[field] |
Removes field from object. |
|
field in obj |
Checks whether field is present in object. |
These methods are defined in a model's ObjectHandler
and act like classmethod
s except they're implemented in a slightly different way; you have to remember that these methods are available only on the model class.
Method name | Example usage | Description |
---|---|---|
all() |
Model.all() |
Retrieves a list of all saved objects for model. |
filter(ids=None, **kwargs) |
Model.filter(['id1', 'id2'], field1=value1, field2=value2) |
Retrieves a list of all saved objects for model, filtered by given list of ids and/or kwargs . |
get(id_=None, **kwargs) |
Model.get('id1') or Model.get(field1=value1, field2=value2)
|
Retrieves a single object for model, filtered either by an id_ or by kwargs . |
create(**kwargs) |
Model.create(field1=value1, field2=value2) |
Instantiates an object for model, saves it to the database and returns it. |
get_or_create(id_=None, **kwargs) |
Model.get_or_create('id1') or Model.get_or_create(field1=value1, field2=value2)
|
Tries to retrieve a single record, filtered either by an id_ or by kwargs . If it succeeds, it returns a tuple like (obj, False) . If it fails, it creates the object and returns a tuple like (obj, True) . |
count() |
Model.count() |
Returns the number of saved objects for model. |
If the basics are not enough for your needs, you can always extend the base model in various ways. Below are presented the most common of them.
If you need to perform a custom query on a model, build the ReQL query directly on the model; then run the query and manipulate the results:
import rethinkdb as r
class Celebrity(Model):
pass
Celebrity.create(name='george clooney')
Celebrity.create(name='kate winslet')
upper = Celebrity.map({'name': r.row['name'].upcase()}).run()
print list(upper) # prints [{u'name': u'GEORGE CLOONEY'}, {u'name': u'KATE WINSLET'}]
In the above example, we wanted to return a list of all celebrities with their names in upper case.
many times the code will look cleaner if you wrap the custom behavior in a custom
ObjectHandler
method; read below on how to do this.
If you need custom behavior for objects, create an instance method within a model declaration:
from remodel.models import Model
class Child(Model):
def is_minor(self):
if 'age' in self:
return self['age'] < 18
jack = Child.create(name='Jack', age=15)
jack.is_minor() # prints True
In the above example, we want to check whether a child object is a minor.
If you need custom behavior for models, extend the default ObjectHandler
and attach it to a model declaration:
from remodel.models import Model
from remodel.object_handler import ObjectHandler, ObjectSet
class TripObjectHandler(ObjectHandler):
def in_europe(self):
return ObjectSet(self, self.query.filter({'continent': 'Europe'}))
class Trip(Model):
object_handler = TripObjectHandler
Trip.create(continent='Europe', city='Paris')
Trip.create(continent='Asia', city='Shanghai')
Trip.create(continent='Europe', city='Dublin')
print len(Trip.in_europe()) # prints 2
We wanted a way to list all trips that were made in Europe. Although we could have used Trip.filter(continent='Europe')
, defining a custom method on an ObjectHandler
makes it cleaner and more extensible. We used ObjectSet
to wrap query results and to allow uses of methods like len()
on them.
Sometimes you want an overview of what fields are defined for an object. You can view a dict of these fields and their values:
class Train(Model):
pass
train = Train.create(nr=12345, destination='Paris', has_restaurant=True, classes=[1, 2])
print train.fields.as_dict()
# prints {u'classes': [1, 2], u'nr': 12345, u'destination': u'Paris', u'has_restaurant': True, u'id': u'd9b8d57f-5d67-4ff7-acf8-cbf7fdd65581'}