Skip to content
Andrei Horak edited this page Feb 28, 2015 · 2 revisions

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).

API

Row-level

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.

Table-level

These methods are defined in a model's ObjectHandler and act like classmethods 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.

Advanced

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.

Custom queries

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.

Custom row-level methods

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.

Custom table-level methods

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.

Viewing object fields

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'}