lac
lac

Reputation: 785

How to make HyperlinkedModelSerializer in Django Rest Framework work for foreignkeys?

I am new to Django Rest Framework and am struggling to get my serialisations to work correctly for a foreignkey relationship between two models. I have tried to reduce my setup down to be as simple as possible but I still can't understand how it is supposed to work. I am trying to use HyperlinkedModelSerializer so (from the docs) 'that it uses hyperlinks to represent relationships'. When I try to visit the url for either the list or detail view for {model X} on the test server I get:

'Could not resolve URL for hyperlinked relationship using view name "{model Y}-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 doing wrong?

My models:

from django.db import models


class Project(models.Model):
    name = models.CharField(max_length=50)
    description = models.TextField()


class ProjectPhoto(models.Model):
    project = models.ForeignKey(
            Project, related_name='photos', on_delete=models.CASCADE
        )
    image = models.ImageField()
    caption = models.CharField(max_length=100)
    date_added = models.DateTimeField(auto_now_add=True)

My serializers

class ProjectSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Project
        fields = ('name', 'description', 'photos')


class ProjectPhotoSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = ProjectPhoto
        fields = ('image', 'caption', 'date_added', 'project'))

My views:

from rest_framework import viewsets

from projects.models import Project, ProjectPhoto
from projects.serializers import ProjectSerializer, ProjectPhotoSerializer


class ProjectViewSet(viewsets.ModelViewSet):
    queryset = Project.objects.all().order_by('name')
    serializer_class = ProjectSerializer


class ProjectPhotoViewSet(viewsets.ModelViewSet):
    queryset = ProjectPhoto.objects.all().order_by('date_added')
    serializer_class = ProjectPhotoSerializer

EDIT:

My urls:

from django.conf.urls import url, include
from rest_framework import routers

from projects import views


router = routers.DefaultRouter()
router.register(r'^projects', views.ProjectViewSet)
router.register(r'^project-photos', views.ProjectPhotoViewSet)

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

these are then added in my main app urls.py file. I don't think this is problem as if I change the serializer to ModelSerializer then everything works fine.

Upvotes: 2

Views: 4527

Answers (1)

Roberth Solís
Roberth Solís

Reputation: 1559

I think your problem is in your urls.py file, see the code and picture

rest/urls.py file

from django.conf.urls import url, include
from rest_framework import routers

from .views import ProjectViewSet, ProjectPhotoViewSet

router = routers.SimpleRouter()
router.register(r'project', ProjectViewSet)
router.register(r'project-photo', ProjectPhotoViewSet)

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

Principal urls.py file:

from django.conf.urls import url, include
from django.contrib import admin

from rest import urls as urls_rest

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^rest/', include(urls_rest)),
]

enter image description here

and other option, try to use this code in your serializers.py file:

from rest_framework import serializers


from .models import Project, ProjectPhoto


class ProjectPhotoSerializer(serializers.ModelSerializer):

  class Meta:
    model = ProjectPhoto
    fields = ('image', 'caption', 'date_added', 'project')


class ProjectSerializer(serializers.ModelSerializer):

  class Meta:
    model = Project
    fields = ('name', 'description', 'photos')
    depth = 2

You have 3 options to use serializers (see picture below) enter image description here

Upvotes: 8

Related Questions