A django rest framework adapter for Inertia https://inertiajs.com/
- Python (2.7, 3.3+)
- Django (1.11, 2.2, 3.0)
- Django REST Framework (2.4, 3.0, 3.1)
Install using pip
…
$ pip install django-rest-inertia
To use django-inertia-rest, decorate your views with the @inertia
decorator
passing it the frontend component:
from rest_framework import views, viewsets
from rest_framework.response import Response
from rest_framework.decorators import api_view
from drf_inertia.decorators import inertia
# on a function based view:
@inertia("User/List")
@api_view(["GET"])
def get_users(request, **kwargs):
return Response(data={"users": []})
# on a class based view:
@inertia("User/List")
class UsersView(views.APIView):
def get(self, request, **kwargs):
return Response(data={"users": []})
Both these views would return the following:
GET: http://example.com/users
Accept: text/html, application/xhtml+xml
X-Inertia: true
X-Inertia-Version: unversioned
HTTP/1.1 200 OK
Content-Type: application/json
{
"component": "User/List",
"props": {
"users": []
},
"url": "/users",
"version": "unversioned"
}
Note that if you make a request to the API without the X-Inertia
headers and using an Accept
header that does not include html,
then you will get a response as though there is no @inertia
decorator:
GET: http://example.com/users
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"users": []
}
For ViewSets, each action may need a different component:
# on a viewset:
@inertia("User/List", retrieve="Users/Detail")
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
Or you can use the @component
decorator:
from drf_inertia.decorators import inertia, component
@inertia("User/List")
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
@component("User/Detail")
def retrieve(self, request, pk=None):
//...
return Response(data=user_data)
Shared data is added using a SharedSerializer. A default implementation DefaultSharedSerializer is provided which includes errors and flash data.
The flash data makes use of Django's messages framework:
from django.contrib import messages
@inertia("User/List")
class UserList(APIView):
def get(self, request):
messages.add_message(request, messages.INFO, 'Got users.')
return Response(data=UserSerializer(User.objects.all(), many=True).data)
# GET /users
{
"component": "User/List",
"props": {
"users": [...],
"flash": {"info": "Got users."}
},
"url": "/users",
"version": "unversioned"
}
Inertia decorated views also have a custom exception handler set. This will catch exceptions, add errors to request.session, and return a 303 response as the inertia protocol demands.
By default the redirect will be to the current request.path but you can override this in your view using set_error_redirect.
Errors added to djangos "request.session" object will show up in the errors field in GET responses via the DefaultSharedSerializer.
from rest_framework import exceptions
from drf_inertia.exceptions import set_error_redirect
@inertia("Users/List")
class UserViewSet(viewsets.ModelViewSet):
# ...
def create(self, request):
set_error_redirect(request, '/users/create') # or reverse('users-create')
# this will invoke the inertia exception handler
# which adds the error to the session and redirects
# back to the request.path
raise exceptions.ValidationError("Cannot create user")
# POST /users {"name": "John Smith", "email": "P@ssword"}
#
# 303 See Other
# Location: /users/create
# GET /users/create
{
"component": "User/Create",
"props": {
"users": [...],
"errors": ["Cannot create user"]
},
"url": "/users/create",
"version": "unversioned"
}
Install testing requirements.
$ pip install -r requirements.txt
Run with runtests.
$ ./runtests.py
You can also use the excellent tox testing tool to run the tests against all supported versions of Python and Django. Install tox globally, and then simply run:
$ tox
To build the documentation, you’ll need to install mkdocs
.
$ pip install mkdocs
To preview the documentation:
$ mkdocs serve
Running at: http://127.0.0.1:8000/
To build the documentation:
$ mkdocs build