django-ripozo tutorial¶
In this tutorial we will create a todo list application.
Setting up Django¶
Note This is not a tutorial for Django. If you need some more info on Django please visit: the django tutorial.
In this tutorial we will create a todo list application. First we need to install the necessary dependencies. It is recommended that you work within a virtualenv.
pip install django-ripozo
This should install an appropriate version of Django as well.
Now we need to create our project and app.
django-admin startproject todolist
You’ll need to sync your database.
python ./manage.py migrate
Now we need to create our todo app.
python ./manage.py startapp todoapp
Now in our todolist/settings.py
we will want to
add 'django_ripozo'
and 'todoapp'
to the
INSTALLED_APPS tuple.
Alright, now we’re going to edit the todoapp/models.py
file and add the following models.
class TaskBoard(models.Model):
title = models.CharField(max_length=50)
class Task(models.Model):
title = models.CharField(max_length=50)
description = models.TextField()
completed = models.BooleanField(default=False)
task_board = models.ForeignKey('TaskBoard', related_name='task_set')
You’ll need to run makemigrations and migrate again.
You’re now all set up and ready to start building your api.
Creating your managers¶
Managers are responsible for handling access
to the django models that you just created.
To start we are going to create a new file in
the todoapp called managers.py
. After that
we are going to set up our managers.
from django_ripozo import DjangoManager
from .models import TaskBoard, Task
class TaskBoardManager(DjangoManager):
# These are the default fields to use when performing any action
fields = ('id', 'title', 'task_set.id',)
update_fields = ('title',) # These are the only fields allowed when updating.
model = TaskBoard
paginate_by = 10
class TaskManager(DjangoManager):
fields = ('id', 'title', 'description', 'completed', 'task_board_id',)
model = Task
paginate_by = 20
That’s how simple it is to set up our managers.
Creating your resources¶
Resources are the core of ripozo. These are common across all manager and dispatcher packages. This means, assuming that the application was developed well, you could reuse the resources in flask or mix them in with the sqlalchemy manager.
The first thing we are going to do is create a file in the todoapp
directory called resources.py
. Then we will add the following
from ripozo import restmixins, ListRelationship, Relationship, apimethod
from .managers import TaskBoardManager, TaskManager
class TaskBoardResource(restmixins.CRUDL):
manager = TaskBoardManager()
resource_name = 'taskboard'
pks = ('id',)
_relationships = (
ListRelationship('task_set', relation='TaskResource'),
)
# We're going to add a simple way to add
# tasks to a board by extending the
@apimethod(route='/addtask', methods=['POST'])
def add_task(cls, request):
body_args = request.body_args
body_args['task_board_id'] = request.get('id')
request.body_args = body_args
return TaskResource.create(request)
class TaskResource(restmixins.CRUD):
manager = TaskManager()
resource_name = 'task'
pks = ('id',)
_relationships = (
Relationship('task_board', property_map=dict(task_board_id='id'), relation='TaskBoardResource'),
)
We now have a reusable core to our RESTful API. This is reusable across various web frameworks, databases (you will have to change the manager), or REST protocol.
Setting up your dispatcher.¶
The dispatcher is responsible for translating the
request into something that the framework (Django)
can understand and translating the ripozo response
into the frameworks preferred method. First create a urls.py
file
in your todoapp directory. In that file:
from django_ripozo import DjangoDispatcher
from ripozo.adapters import SirenAdapter, HalAdapter
from .resources import TaskBoardResource, TaskResource
dispatcher = DjangoDispatcher(base_url='/api')
dispatcher.register_resources(TaskBoardResource, TaskResource)
dispatcher.register_adapters(SirenAdapter, HalAdapter)
urlpatterns = dispatcher.url_patterns
And right there you’ve set up your url patterns and registered the resources with the application.
Using the api¶
We’ll be using pypermedia to access the api. It makes it extremely easy to use a SIREN based protocol. You could use HAL protocol if you preferred by prepending that to your accept-types.
pip install pypermedia
First we’ll create a task board
>>> siren_client = HypermediaClient.connect('http://127.0.0.1:5000/api/taskboard/', request_factory=requests.Request)
>>> task_board_list = siren_client.retrieve_list()
>>> created = task_board_list.create(title='My First Board')
>>> retrieve = created.retrieve()
>>> print(created.title)
'My First Board'
>>> print(created.id)
5
Now we can update the board’s title.
>>> updated = retrieve.update(title='My Updated Board')
>>> print(updated.title)
'My Updated Board'
Of course we can’t have a task board without any tasks!
>>> new_task = updated.add_task(title='My first task', description='I need to do something')
>>> print(new_task.title)
'My first task'
>>> print(new_task.description)
'I need to do something'
>>> print(new_task.completed)
False
We can now get this task from the task board itself.
>>> task_board = retrieve.retrieve()
>>> task = next(task_board.get_entities('tasks'))
>>> print(task.description)
'I need to do something'
>>> print(task.completed)
False
Well I guess we did something. We’ll update the task.
>>> task = task.update(completed=True)
>>> print(task.completed)
True
And we can get the board this task belonds to by getting the task_board entity
>>> parent_board = next(task.get_entities('task_board'))
>>> print(parent_board.title)
'My Updated Board'
That task is dumb. Let’s delete it.
>>> deleted = task.delete()
>>> original_task = task.retrieve()
>>> print(original_task)
None