0

I am having my models.py file defined as below:-

from django.db import models
from django.contrib.auth.models import User

class Custom_User(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    mobile = models.CharField(max_length=20)
    REGISTRATION_CHOICES = (
        ('Learner', 'Learner'),
        ('Trainer', 'Trainer'),
    )
    primary_registration_type = models.CharField(max_length=15, choices=REGISTRATION_CHOICES)    

    def __str__(self):
        return self.user.email

As you can see that my Custom_User model uses Django's User model as its foreign Key.

For the above model I have defined my serialziers.py file like this:-

from django.contrib.auth.models import User
from rest_framework import serializers
from .models import *

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'username', 'email')


class Custom_UserSerializer(serializers.HyperlinkedModelSerializer):
    user = UserSerializer()
    class Meta:
        model = Custom_User
        fields = ('__all__')

Now I am using this serializers in my viewsets like below:-

from django.contrib.auth.models import User
from rest_framework import viewsets
from .serializers import *


class UserViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all()
    serializer_class = UserSerializer



class Custom_UserViewSet(viewsets.ModelViewSet):
    queryset = Custom_User.objects.all()
    serializer_class = Custom_UserSerializer



class TrainerViewSet(viewsets.ModelViewSet):
    queryset = Custom_User.objects.filter(primary_registration_type="Trainer")
    serializer_class = Custom_UserSerializer


class LearnerViewSet(viewsets.ModelViewSet):
    queryset = Custom_User.objects.filter(primary_registration_type="Learner")
    serializer_class = Custom_UserSerializer

And Finally inside my urls.py file I register them as below:-

from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'users', api_mailing_list_views.UserViewSet)
router.register(r'custom_users', api_mailing_list_views.Custom_UserViewSet)
router.register(r'trainers', api_mailing_list_views.TrainerViewSet)
router.register(r'learners', api_mailing_list_views.LearnerViewSet)


urlpatterns = [
    path('admin/', admin.site.urls),
    path('', mailing_list_views.index, name='index'),
    path('api/', include(router.urls)),
    path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]

As I was expecting the urls list to be like below in my browser:

{
    "users": "http://localhost:8080/api/users/",
    "custom_users": "http://localhost:8080/api/custom_users/",
    "trainers": "http://localhost:8080/api/trainers/",
    "learners": "http://localhost:8080/api/learners/"
}

But what i get instead is a list of urls like this:-

{
    "users": "http://localhost:8080/api/users/",
    "custom_users": "http://localhost:8080/api/trainers/",
    "trainers": "http://localhost:8080/api/trainers/",
    "learners": "http://localhost:8080/api/trainers/"
}

However I am not getting any errors or if I visit the following url:-

http://localhost:8080/api/learners/

which is not showing up in the urls list I still get the filtered list of learners in JSON format.

Thanks for the help in advance.

2 Answers 2

2

you need to provide basename during router register as all of them actually from same custom_user model.

router = routers.DefaultRouter()
router.register(r'users', api_mailing_list_views.UserViewSet, basename='users')
router.register(r'custom_users', api_mailing_list_views.Custom_UserViewSet, basename='custom_user')
router.register(r'trainers', api_mailing_list_views.TrainerViewSet, basename='trainers')
router.register(r'learners', api_mailing_list_views.LearnerViewSet, basename='learners')
Sign up to request clarification or add additional context in comments.

Comments

2

Django-rest-framework's router tries to identify the viewset by its model/queryset, since both viewsets use the same model things most likely get mixed up. From the documentation:

If unset the basename will be automatically generated based on the queryset attribute of the viewset, if it has one. Note that if the viewset does not include a queryset attribute then you must set basename when registering the viewset.

Try providing a basename to the router:

router.register(r'custom_users', api_mailing_list_views.Custom_UserViewSet, basename='custom_users')
router.register(r'trainers', api_mailing_list_views.TrainerViewSet, basename='trainers')
router.register(r'learners', api_mailing_list_views.LearnerViewSet, basename='learners')

1 Comment

this is actually correct answer, but this time i did post it earlier. What should we do for this case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.