shubhpy shubhpy - 1 month ago 6
Python Question

How to list related objects in Django Rest Framework

I am trying to add a new field in a model serializer which will show all the related values of this model to another.

Like as I have following :

models.py

from django.db import models

class University(models.Model):
name = models.CharField(max_length=50)

def __unicode__(self):
return self.name

class Student(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
university = models.ForeignKey(University)

def __unicode__(self):
return '%s %s' % (self.first_name, self.last_name)


views.py

from rest_framework import viewsets
from .models import University, Student
from .serializers import UniversitySerializer, StudentSerializer

class StudentViewSet(viewsets.ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentSerializer

class UniversityViewSet(viewsets.ModelViewSet):
queryset = University.objects.all()
serializer_class = UniversitySerializer


serializers.py

from rest_framework import serializers
from .models import University, Student

class UniversitySerializer(serializers.ModelSerializer):
class Meta:
model = University

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


and

urls.py

from rest_framework import routers
from core.views import StudentViewSet, UniversityViewSet
from django.conf import settings
from django.conf.urls import url, include
from django.contrib import admin

router = routers.DefaultRouter()
router.register(r'students', StudentViewSet)
router.register(r'universities', UniversityViewSet)

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include('apps.core.urls', namespace='core')),
]


and now i am writing rest-api using django-rest-framework so i get like this

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
"students": "http://127.0.0.1:8000/api/students/",
"universities": "http://127.0.0.1:8000/api/universities/"
}


now when i click http://127.0.0.1:8000/api/universities/. I get

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
{
"id": 1,
"name": "test42"
},
{
"id": 2,
"name": "xxxxxx1222"
},
{
"id": 3,
"name": "MIT"
}
]


and this on clicking http://127.0.0.1:8000/api/students/

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
{
"id": 35,
"first_name": "Gugu",
"last_name": "Gaga",
"university": 11
},
{
"id": 36,
"first_name": "qwer",
"last_name": "abcd",
"university": 12
}
]


So as student has a particular university no so i want to add a list of ids of students in a university.
Like

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
{
"id": 1,
"name": "test42"
"students" : {42,56,78}
},
{
"id": 2,
"name": "xxxxxx1222"
"students" : {2,6,8}
},
{
"id": 3,
"name": "MIT"
"students" : {4,5,7}
}
]


How to do that?

Answer

You can make use of PrimaryKeyRelatedField for this. First set related_name attribute to your foreign key.

university = models.ForeignKey(University, related_name='students')

And then change your serializer like this.

class UniversitySerializer(serializers.ModelSerializer):
    students = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
    class Meta:
        model = University

Hope this helps :)