Довольно мутные интерфейсы в DRF ... с ходу не разберешься, "Django" он называется видимо только потому, что просто умеет с Django ORM работать, интерфейсы и подходы как-то не очень Django-frendly
Пишу весь код в одну кучу, критика приветствуется.
from django.conf.urls import patterns
from django.core.exceptions import PermissionDenied
from django.db import models
from django.db.models.base import ModelBase
from django.utils.decorators import available_attrs
from rest_framework.permissions import IsAuthenticated
from rest_framework.status import HTTP_500_INTERNAL_SERVER_ERROR
# Наш документ в models.py
document_make_some_permission = 'document_custom_permission'
class Document(models.Model):
    class Meta:
        permissions = [
            (document_make_some_permission, "make_some доступ"),
        ]
    @classproperty
    def make_some_permission(cls):
        """ Возвращает полный код доступа """
        return permission_code(cls, document_make_some_permission)
    name = models.CharField(max_length=250)
    type = models.CharField(max_length=20)
# В settings.py делаем настройки для DRF
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.SessionAuthentication',  # Авторизация через сессии Django
    ),
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoObjectPermissions'  # Доступ к объектам через Django
    ],
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',  # Если надо через браузер вручную удобно дёргать api
    )
}
# Создаем router и затем уже регистрируем его в urls.py
from rest_framework import routers
api_router = routers.DefaultRouter()
from rest_framework import serializers, viewsets
from rest_framework.decorators import list_route
from rest_framework.filters import DjangoFilterBackend
from rest_framework.response import Response
# Делаем serializer
class DocumentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Document
    def validate_name(self, value):
        # Валидация отдельных полей
        if not value:
            raise serializers.ValidationError("Error")
        return value
    def validate(self, data):
        # Валидация на уровне объекта
        if not data.get('name', None):
            raise serializers.ValidationError("Error")
        return data
# Делаем ViewSet (по сути форма)
class DocumentViewSet(viewsets.ModelViewSet):
    serializer_class = DocumentSerializer
    # Если нужна возможность фильтрации
    filter_backends = (DjangoFilterBackend,)
    # Разрешаем фильтрацию только по отдельным полям
    filter_fields = ('name',)
    # Можно переопределить к каким объектам ViewSet будет предоставлять доступ
    queryset = Document.objects.all()
    # На этом собственно всё, если нужен только простой REST с поддержкой доступов Django
    # Если нужны свои методы в API для Document
    @list_route(permission_classes=[IsAuthenticated, ])  # permission_classes приведён для примера
    @permission_required_action(Document.make_some_permission)  # Об этом декораторе ниже
    def make_some(self, request):
        """
        @list_route означает, что метод будет доступен для всех Document (т.е. в нашем случае метод будет доступен
        по адресу /api/document/make_some), если нужен метод который будет доступен для конкретного объекта то
        надо использовать декоратор detail_route (метод будет доступен по адресу /api/document/1/make_some)
        Не забываем про доступы ... для list_route и detail_route модно задавать permission_classes и authentification_classes, о них в документации
        Чтобы проверить свой доступ Django для Document (созданный в Document.Meta) начинается цирк,
        т.к. встроенного механизма проверки такого доступа нет и надо либо делать свой MyCustomDocumentPersmissionClass унаследованный от BasePermission
        с реализацией has_permission и задавать его в permission_classes, либо делать проверку в коде метода make_some request.user.has_perm,
        либо адаптировать встроенный декторатор Django persmission_required (адаптировать надо потому, что декоратор рассчитан на function based view,
        а у нас метод класса который первым аргументом принимает self, моя реализация в конце в persmission_required_action).
        """
        try:
            result = Document.objects.filter(type='some')
        except Exception as e:
            # Ошибка, можно например вернуть произвольный JSON
            return Response({'result': 'error', 'msg': str(e)}, status=HTTP_500_INTERNAL_SERVER_ERROR)
        # Если надо вернуть массим объектов
        vs = DocumentViewSet(result, many=True)  # Может быть можно сам DocumentSerializer тут использовать, но так просто работает и проблем не доставляет
        return Response(vs.data)
    def get_permissions(self):
        # А ещё в ViewSet доступ можно проверить переопределив get_permissions ...
        from rest_framework.permissions import IsAuthenticated
        if self.action == 'make_some':
            return [IsAuthenticated(), ]
        return super().get_permissions()
# Регистрируем ViewSet в router
api_router.register('document', DocumentViewSet, base_name='document')
# В urls.py регистрируем router
urlpatterns = patterns('',
                       url(r'^api/', include(api_router.urls)),
                       )
# Собственно всё
"""
Вспомогательные вещи
"""
from functools import wraps
class classproperty(property):
    def __get__(self, cls, owner):
        return classmethod(self.fget).__get__(None, owner)()
def permission_code(class_or_model, permission_name):
    if isinstance(class_or_model, ModelBase):
        return '{0}.{1}'.format(class_or_model._meta.app_label, permission_name)
    raise Exception('Не могу составить код для {0} {1}'.format(class_or_model, permission_name))
from django.contrib.auth import REDIRECT_FIELD_NAME
def user_passes_test_action(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    def decorator(view_func):
        @wraps(view_func, assigned=available_attrs(view_func))
        # Тут первым параметром идёт self, а запрос уже вторым
        def _wrapped_view(object, request, *args, **kwargs):
            if test_func(request.user):
                return view_func(object, request, *args, **kwargs)
            else:
                raise PermissionDenied()
        return _wrapped_view
    return decorator
def permission_required_action(perm, login_url=None, raise_exception=False):
    def check_perms(user):
        if not isinstance(perm, (list, tuple)):
            perms = (perm,)
        else:
            perms = perm
        # First check if the user has the permission (even anon users)
        if user.has_perms(perms):
            return True
        # In case the 403 handler should be called raise the exception
        if raise_exception:
            raise PermissionDenied
        # As the last resort, show the login form
        return False
    return user_passes_test_action(check_perms, login_url=login_url)