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:
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