0
votes

Similar to this question, but I do not have namespaces or base-names, so none of the solutions in that question have worked.

I have 2 models: Organisation Student

A student can belong to an organisation.

When I retrieve an organisation, I want a child object in the returned JSON that lists the 'related' students as hyperlinked urls (as per HATEOS).

models.py

class Organisation(TimeStampedModel):
  objects = models.Manager()
  name = models.CharField(max_length=50)

  def __str__(self):
    return self.name

class Student(TimeStampedModel):
  objects = models.Manager()
  first_name = models.CharField(max_length=50)
  last_name = models.CharField(max_length=50)
  email = models.EmailField(unique=True)
  organisation = models.ForeignKey(to=Organisation, on_delete=models.SET_NULL, default=None, null=True, related_name='students')

serializers.py

class OrganisationSerializer(serializers.ModelSerializer):
  students = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='student-detail', lookup_url_kwarg='organisation_id')

  class Meta:
    model = Organisation
    fields = ('id', 'name','students')

class StudentSerializer(serializers.ModelSerializer):
  class Meta:
    model = Student
    fields = '__all__'

urls.py

from rest_framework import routers
from .views import OrganisationViewSet, StudentViewSet

from django.conf.urls import url

router = routers.DefaultRouter()
router.register(r'api/v1/organisations', OrganisationViewSet)
router.register(r'api/v1/students', StudentViewSet)

urlpatterns = router.urls

views.py

from .models import Organisation, Student
from rest_framework import viewsets, permissions
from .serializers import OrganisationSerializer, StudentSerializer

# Organisation Viewset
class OrganisationViewSet(viewsets.ModelViewSet):
  queryset = Organisation.objects.all()
  serializer_class = OrganisationSerializer
  permission_classes = [
    permissions.AllowAny
  ]

# Student Viewset
class StudentViewSet(viewsets.ModelViewSet):
  queryset = Student.objects.all()
  serializer_class = StudentSerializer
  permission_classes = [
    permissions.AllowAny
  ]

So this should work as this is pretty boiler-plate code. Or maybe I don't understand something?

1

1 Answers

1
votes

As per the URL configuration and StudentViewSet , you don't have to provide the lookup_url_kwarg value in the HyperlinkedRelatedField. So, your serializer will become as,

class OrganisationSerializer(serializers.ModelSerializer):
    students = serializers.HyperlinkedRelatedField(many=True,
                                                   read_only=True,
                                                   view_name='student-detail')

    class Meta:
        model = Organisation
        fields = ('id', 'name', 'students')