Let’s use djangorestframework create a REST endpoint to register new users. We’ll assume you have already set up a virtual environment and it is activated. To install Django and some other things pip install a requirements.txt file that looks like this one, which is part of a working example on Github.

django_rest_app/requirements.txt

Django==1.9.6
ipython==4.2.0
ipdb==0.10.0
requests==2.10.0
djangorestframework==3.3.3

Then from the command line:

django-admin.py startproject django_rest_app

This creates a project called django_rest_app. In that project we’ll create an app for registering users.

python manage.py startapp registration

Before we take a look at the registration app, let’s tell the main project about the apps we have. Open up the settings file and add ‘registration’ and ‘rest_framework’ and ‘rest_framework.auth_token’ as installed apps. Not only would we like to register users, we would also like to associate those users with an API token so that client devices can authenticate without passing a username and password.

Generally I would create the models first and then tackle the endpoints that manipulate the model, but this time we’re going to use a Django model so we’ll skip to writing the urls.

django_rest_app/urls.py

from django.conf.urls import include, url
urlpatterns = [
        url('^registration/', include('registration.urls')),
]

registration/urls.py

from django.conf.urls import url
from registration import views
from rest_framework.authtoken.views import obtain_auth_token

urlpatterns = [
    url(r'^users/(?P<pk>[0-9]+)/$', views.GetUser.as_view(), name='user-detail'),
    url(r'^users/new/$', views.NewUser.as_view()),
]

Our /users/new endpoint passes information to the NewUser view, which, through djangorestframework, we’ll make respond to POST requests. Our /users/(?P[0-9]+)/ endpoint is using the GetUser view class to respond to GET requests. Let’s look at those views.

from django.contrib.auth.models import User
from registration import serializers
from registration.models import UserProfile
from rest_framework import generics
from rest_framework.authentication import TokenAuthentication
from rest_framework.response import Response

class NewUser(generics.CreateAPIView):
    queryset = User.objects.all()
    serializer_class = serializers.UserSerializer

class GetUser(generics.RetrieveAPIView):
    authentication_classes = (TokenAuthentication, )
    queryset = User.objects.all()
    serializer_class = serializers.UserSerializer

The NewUser class extends generics.CreateAPIView, which is a DRF class that responds to post requests. In fact, if you have the need, you can override the post method in this class to do some special things with the data that comes along with the request. With the queryset attribute, we’re making all the User objects available to be queried. We use the serializer_class to explain how we’re going to do the serialization of the User.

GetUser follows suit and additionally uses authentication_classes to indicate these objects cannot be accessed without a proper token.

To find out what data we need post to /users/new we can look at the UserSerializer.

from django.contrib.auth.models import User
from rest_framework import serializers
from rest_framework.authtoken.models import Token


class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ('id', 'username', 'password', 'email')
        extra_kwargs = {'password':{'write_only': True}}

    def create(self, validated_data):
        user = User.objects.create_user(
                   username=validated_data['username'],
                   email=validated_data['email'],
                   password=validated_data['password'])
        Token.objects.create(user=user)
        UserProfile.objects.create(user=user)
        return user

The Meta class indicates that we would like to serialize the User model and we’re concerned about serializing the fields id, username, password and email. Extra_kwargs ensures the password is ‘write only’ meaning that it would not be returned in a json representation of the user. To further clarify, the following JSON would be appropriate here for a POST request to /user/new:

{'username': 'ImaUser', 'password': 'secret', 'email': 'imauser@email.com'}

If we were running a server at localhost:8080 and sent that json as the data of a post request, the response should look something like this:

{"id":6,"username":"ImaUser","email":"imauser@email.com"}

The other thing we do when creating the user is associate it with a Token object provided by djangorestframework. We can do this in the UserSerializer, which has a create method we can override. We can check the data and use it to create a user. We can also create a new token and associate it with the user.

Why is it nice to use Token authentication? We can make requests using the token as a way to authenticate the user without having to send a password with the request. It also gives us the power to invalidate the token, forcing the user to login again.

Once the user is created, the registration is complete. Start the Django development server and then open an interactive python session.

Python 3.4.3 (default, Jul 13 2015, 12:18:23)
Type "copyright", "credits" or "license" for more information.

IPython 4.2.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.

In [1]: import requests

In [2]: response = requests.post('http://127.0.0.1:8000/registration/users/new/', data={'username':'app_user', 'password':'top_secret', 'email':'my_email@email.com'})

In [3]: response.status_code
Out[3]: 201

In [4]: response.content
Out[4]: b'{"id":8,"username":"app_user","email":"my_email@email.com"}'

For more, look at this sample rest app, which adds additional endpoints and includes implementations for testing your rest api.