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
'todoapp' to the
Alright, now we’re going to edit the
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
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
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