Skip to content
Advertisement

Creating django api view that returns filtered objects

Problem Description
I’m new to django-rest-framework and got a problem in my view. I have three models namely #User, #Profession and #StudentProfessions. I need to create an api-view that takes user_id as request-parameter and returns a list of all professions that belongs to a particular user_id.

Here’s My Codes

profession_app >> models.py

from django.db import models

class Profession(models.Model):
    profession_name = models.CharField(max_length=100)

    def __str__(self):
        return self.profession_name

User Model

I used the django default model.

student_profile_app >> models.py

from django.contrib.auth.models import User
from department_app.models import Department
from profession_app.models import Profession
from program_app.models import Program
from django.db import models

class StudentProfile(models.Model):
    student_status = models.BooleanField()
    phone_number = models.CharField(max_length=100)
    year_of_study = models.CharField(max_length=100)
    program_id = models.ForeignKey(Program, on_delete=models.CASCADE)
    student_id = models.OneToOneField(User, on_delete=models.CASCADE, related_name="student_id")
    organization_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="organization_id")
    profile_image = models.ImageField(upload_to='images/', blank=True)
    field_supervisor_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="field_supervisor")
    department_id = models.ForeignKey(Department, on_delete=models.CASCADE)
    academic_supervisor_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="academic_supervisor")

    def __str__(self):
        return f'{self.student_id.username } Profile'


class StudentProfession(models.Model):
    student_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="student_profession_id")
    profession_id = models.ForeignKey(Profession, on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.student_id.username } Profession' 

student_profile_app >> views.py

from .models import StudentProfile, StudentProfession

def getStudentProfessions(request, studentId):
    professions = StudentProfession.objects.filter(student_id=studentId)
    return professions

And In My urls

from student_profile_app.views import getStudentProfessions
from rest_framework import routers

router.register('getStudentProfessions/<int:studentId>', getStudentProfessions, 'getStudentProfessions')

urlpatterns = router.urls

But when i run the server i got the following error

    urlpatterns = router.urls
  File "E:CodesFIPfipEnvlibsite-packagesrest_frameworkrouters.py", line 77, in urls
    self._urls = self.get_urls()
  File "E:CodesFIPfipEnvlibsite-packagesrest_frameworkrouters.py", line 338, in get_urls
    urls = super().get_urls()
  File "E:CodesFIPfipEnvlibsite-packagesrest_frameworkrouters.py", line 236, in get_urls
    routes = self.get_routes(viewset)
  File "E:CodesFIPfipEnvlibsite-packagesrest_frameworkrouters.py", line 152, in get_routes
    extra_actions = viewset.get_extra_actions()
AttributeError: 'function' object has no attribute 'get_extra_actions'

Advertisement

Answer

First of all StudentProfession.student_id has bad model parameter set (its related to User model – it should be Student model).

Django rest framework uses viewset’s for routers. What you need is serializer which will represent your endpoint api structure and viewset.

I will write simple serializer and viewset for you but you really need to read docs.

After edits from comments:

Serializer class:

from rest_framework import serializers
#...other imports

class StudentProfessionSerializer(serializers.ModelSerializer):
    class Meta:
        model = StuedentProfession
        fields = ('profession')

Viewset class (that’s what you register in router !)

from rest_framework import viewsets, mixins
#...other imports

class StudentProfessionViewSet(viewsets.GenericViewSet,
                               mixins.ListModelMixin,
                               mixins.RetrieveModelMixin):
    serializer_class = StudentProfessionSerializer
    queryset = StudentProfession.objects

    def get_queryset(self):
        student_id = self.kwargs.get('studentId')
        return self.queryset.filter(student_id=student_id)

Some tips from me:

  • READ DOCS

  • you dont need to write “_id” suffix in ForeignKey fields (django make it automatically underhood – means that columns in your table will have _id suffix anyway) and then you can use params without this ugly _id… like this

     StudentProfession.objects.filter(student=somestudentid)
    
  • your API should be constructed like

     router.register(r'students/(?P<studentId>d+)/professions', StudentProfessionViewSet, 'student-profession')
    
  • try not to use “real” ID’s of objects in url – use UUID’s instead – its safer

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement