0

I am trying to simply change my ModelSerializer to HyperlinkedModelSerializer to include the url to each of the objects listed in the ListView of the default Browsable API.

According to the docs, since I am using default 'pk' for the lookup, I just change the class I inherit the serializer from:

# class SeasonSerializer(serializers.ModelSerializer):
class SeasonSerializer(serializers.HyperlinkedModelSerializer):

    # url = serializers.HyperlinkedIdentityField(
    #     view_name='season', lookup_field='pk') ---> Not needed according to docs but have also tried with this

    class Meta:
        model = Season
        fields = ('id', 'url', 'years', 'active')

And add the context when instantiating it in the view:

class SeasonListView(APIView):

    def get(self, request, *args, **kwargs):
        queryset = Season.objects.all().order_by('years')
        serializer = SeasonSerializer(
            queryset, many=True, context={'request': request})
        print('INFO: ', serializer)
        permission_classes = [ ]
        authentication_classes = [ ]
        return Response({"Seasons": serializer.data})

class SeasonDetailView(APIView):

    def get(self, request, *args, **kwargs):
        pk = kwargs['pk']
        season = get_object_or_404(Season, pk=pk)
        serializer = SeasonSerializer(season, context={'request': request})
        # print('Data: ', serializer.data) --> this breaks
        return Response(serializer.data)

And my endpoints are the same as when using ModelSerializer:

urlpatterns = [
    path(r'seasons/', SeasonListView.as_view(), name='season-list'),
    path(r'seasons/<int:pk>/', SeasonDetailView.as_view(), name='season-detail'),
]

The error is the following:

For http://localhost:8000/api/seasons/1/

Exception Type: ImproperlyConfigured
Exception Value:    
Could not resolve URL for hyperlinked relationship using view name "season-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

And for http://localhost:8000/api/seasons/

Exception Type: ImproperlyConfigured
Exception Value:    
Could not resolve URL for hyperlinked relationship using view name "season-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

What am I missing here?

Thanks!

1 Answer 1

1

After many days I think I found the problem so I am posting here in case I can save someone that much time!

The problem resides basically in how you handle your routes.

if ( you are using a Router for each application ) :.
Then you must add a basename of the object when you register in the router and manually define the url field in the serializer. Don't forget to add the name of the application like "app:model". For instance:

router.register(r'seasons', SeasonViewSet, basename='seasons')
class SeasonSerializer(serializers.HyperlinkedModelSerializer):
    url = serializers.HyperlinkedIdentityField(view_name="accounts:seasons-detail")
    class Meta:
        model = Season
        fields = ('url', 'id', '...')

if ( you are using 1 router to nest the rest of the routers from the different apps ) :

Like they do in here. Then you need to remove the app from the "app:model" definition of the url field.

I strongly recommend to use django-extesions to use python manage.py show_urls to be aware of the endpoints available in your project.
Thanks to it I was able to figure out what was going out. Take a look at the comparisons when I added my API root.

(base) ➜  Betcomm git:(master) ✗ docker-compose exec app python manage.py show_urls | grep api/

/api/accounts/profiles/ accounts.views.ProfileViewSet   accounts:profiles-list
/api/accounts/profiles/<pk>/    accounts.views.ProfileViewSet   accounts:profiles-detail
/api/accounts/season-profiles/  accounts.views.SeasonProfileViewSet accounts:season-profiles-list
/api/accounts/season-profiles/<pk>/ accounts.views.SeasonProfileViewSet accounts:season-profiles-detail
/api/accounts/users/    accounts.views.UserViewSet  accounts:users-list
/api/accounts/users/<pk>/   accounts.views.UserViewSet  accounts:users-detail
/api/seasons/seasons/   seasons.views.SeasonViewSet seasons:seasons-list
/api/seasons/seasons/<pk>/  seasons.views.SeasonViewSet seasons:seasons-detail


(base) ➜  Betcomm git:(master) ✗ docker-compose exec app python manage.py show_urls | grep api/

/api/   rest_framework.routers.APIRootView  api-root
/api/\.<format>/    rest_framework.routers.APIRootView  api-root
/api/profiles/  accounts.views.ProfileViewSet   profiles-list
/api/profiles/<pk>/ accounts.views.ProfileViewSet   profiles-detail
/api/profiles/<pk>\.<format>/   accounts.views.ProfileViewSet   profiles-detail
/api/profiles\.<format>/    accounts.views.ProfileViewSet   profiles-list
/api/season-profiles/   accounts.views.SeasonProfileViewSet seasonprofiles-list
/api/season-profiles/<pk>/  accounts.views.SeasonProfileViewSet seasonprofiles-detail
/api/season-profiles/<pk>\.<format>/    accounts.views.SeasonProfileViewSet seasonprofiles-detail
/api/season-profiles\.<format>/ accounts.views.SeasonProfileViewSet seasonprofiles-list
/api/seasons/   seasons.views.SeasonViewSet seasons-list
/api/seasons/<pk>/  seasons.views.SeasonViewSet seasons-detail
/api/seasons/<pk>\.<format>/    seasons.views.SeasonViewSet seasons-detail
/api/seasons\.<format>/ seasons.views.SeasonViewSet seasons-list
/api/users/ accounts.views.UserViewSet  users-list
/api/users/<pk>/    accounts.views.UserViewSet  users-detail
/api/users/<pk>\.<format>/  accounts.views.UserViewSet  users-detail
/api/users\.<format>/   accounts.views.UserViewSet  users-list
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.