Orator 0.6 is now out. This version introduces model events, query pagination and performance improvements and fixes.
The stable version is actually the 0.6.1 version.
The 0.6 version introduced bugs in how relationships were handled, breaking the functionality. Everything should now be fixed in 0.6.1.
See the corresponding announcement for more information.
Orator models fire several events, allowing you to hook into various points in
the model's lifecycle using the following methods:
Whenever a new item is saved for the first time, the
created events will fire.
If an item is not new and the
save method is called, the
updated events will fire.
In both cases, the
saved events will fire.
Cancelling save operations via events
False is returned from the
the action will be cancelled:
User.creating(lambda user: user.is_valid())
To consolidate the handling of model events, you can register a model observer.
An observer class can have methods that correspond to the various model events.
saving methods can be on an observer,
in addition to any other model event name.
So, for example, a model observer might look like this:
class UserObserver(object): def saving(user): # ... def saved(user): # ...
users = db.table('users').paginate(15, 2)
Currently, pagination operations that use a
group_by statement cannot be executed efficiently by Orator.
If you need to use a
group_by with a paginated result set, it is recommended that you query the database and create a paginator manually.
You can also paginate ORM queries. In this example, we will paginate the
User model with
15 items per page
for the second page. As you can see, the syntax is nearly identical to paginating query builder results:
all_users = User.paginate(15, 2)
Of course, you can call paginate after setting other constraints on the query:
some_users = User.where('votes', '>', 100).paginate(15, 2)
If you only need "Next" and "Previous" pages in your pagination,
you have the option of using the
simple_paginate method to perform a more efficient query.
some_users = User.where('votes', '>', 100).simple_paginate(15, 2)
Creating a Paginator manually
Sometimes you may wish to create a pagination instance manually, passing it a list of items.
You can do so by creating either a
Paginator or a
LengthAwarePaginator instance, depending on your needs.
Paginator class does not need to know the total number of items in the result set;
however, because of this, the class does not have methods to retrieve the index of the last page.
LengthAwarePaginator accepts almost the same arguments as the
except that it does require a count of the total number of items in the result set.
In other words, the
Paginator corresponds to the
simple_paginate method on the query builder
and the ORM, while the
LengthAwarePaginator corresponds to the
When you call the
simple_paginate methods on a query builder or ORM query,
you will receive a paginator instance. When calling the
you will receive an instance of
LengthAwarePaginator. When calling the
you will receive an instance of
Paginator. These objects provide several methods and attributes
that describe the result set. In addition to these helpers methods, the paginator instances are iterators
and may be looped as a list.
for user in some_users: print(user.name)
Additional attributes and helper methods
You may also access additional pagination information via the following methods and attributes on paginator instances:
| Method or attribute | Description |
results.count() | Returns the number of results on the current page |
results.current_page | The current page of the paginator |
results.has_more_pages() | Returns
True if there is more pages else
results.last_page | The number of the last page (Not available when using
results.next_page | The number of the next page if it exists else
results.per_page | The number of results per page |
results.previous_page | The number of the previous page if it exists else
results.total | The total number of results (Not available when using
Converting Results To JSON
The Orator paginator result classes expose the
so it's very easy to convert your pagination results to JSON.
By default, it will return the JSON formatted underlying
some_users = User.where('votes', '>', 100).paginate(15, 2) print(some_users.to_json())
For the full list of changes, see the CHANGELOG
Finally, here are some features targeted for future versions (actual roadmap to be determined):
Extra functionalities, like caching.