Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework 3.0 to_representation not implemented

I'm upgrading from Django Rest Framework 2.4 to 3.0.1 using Django 1.7.1 and Python 2.7 and can't get past the following error:

File "/Users/bjacobel/.virtualenvs/hey/lib/python2.7/site-packages/rest_framework/fields.py", line 375, in to_representation
    raise NotImplementedError('to_representation() must be implemented.')

The code I'm using worked just fine under 2.4 and I'm struggling to find any documentation on what changed in the DRF classes I'm using. I commented out everything but one of my endpoints (the one that provides CRUD for django.contrib.auth.models.User and I still get the error.

serializers.py:

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

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'first_name', 'last_name', 'email', 'username')

views.py:

from django.contrib.auth.models import User
from hey.apps.api import serializers
from rest_framework import viewsets, permissions, filters

class User(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = serializers.UserSerializer
    permission_classes = (permissions.IsAuthenticated,)
    filter_backends = (filters.OrderingFilter,)

urls.py:

from django.conf.urls import patterns, url, include
from hey.apps.api import views
from rest_framework.routers import SimpleRouter

router = SimpleRouter()


router.register(r'user', views.User)

urlpatterns = patterns('',
    url(r'^', include(router.urls)),
)

pagination.py

from rest_framework import pagination
from rest_framework import serializers

class LinksSerializer(serializers.Serializer):
    next = pagination.NextPageField(source='*')
    prev = pagination.PreviousPageField(source='*')

class CustomPaginationSerializer(pagination.BasePaginationSerializer):
    links = LinksSerializer(source='*')  # Takes the page object as the source
    total_results = serializers.Field(source='paginator.count')

    results_field = 'objects'

settings.py

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_SERIALIZER_CLASS': 'hey.apps.api.pagination.CustomPaginationSerializer',
    'PAGINATE_BY': 20,                  # Default to 20
    'PAGINATE_BY_PARAM': 'limit',       # Allow client to override, using `?limit=xxx`.
    'MAX_PAGINATE_BY': 100,             # Maximum limit allowed when using `?limit=xxx`.
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    )
}

Thank you.

like image 277
bjacobel Avatar asked Dec 13 '14 18:12

bjacobel


1 Answers

The issue is in your pagination serializer, as you are using serializers.Field which is now serializers.ReadOnlyField in Django REST Framework 3.0. This is a subtle change that was made, though it is called out in the release announcement, and it's most noticeable for those who were overriding pagination serializers.

The updated default pagination serializer uses ReadOnlyField for the count field. You should be able to fix your serializer by just swapping out the field.

class CustomPaginationSerializer(pagination.BasePaginationSerializer):
    links = LinksSerializer(source='*')  # Takes the page object as the source
    total_results = serializers.ReadOnlyField(source='paginator.count')

    results_field = 'objects'
like image 172
Kevin Brown-Silva Avatar answered Oct 13 '22 22:10

Kevin Brown-Silva