Django Rest Framework urls.py搞砸了

时间:2019-02-25 13:16:08

标签: django django-rest-framework

我将我的models.py文件定义如下:-

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

您会看到我的Custom_User模型使用Django的User模型作为其外键。

对于上述模型,我已如下定义了serialziers.py文件:-

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__')

现在,我在如下所示的视图集中使用此序列化器:-

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

最后,在我的urls.py文件中,将它们注册如下:-

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')),
]

我期望浏览器中的网址列表如下所示:

{
    "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/"
}

但是我得到的却是这样的网址列表:-

{
    "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/"
}

但是我没有出现任何错误,或者访问以下网址:-

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

未显示在urls列表中,我仍然获得JSON格式的已过滤学习者列表。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您需要在路由器注册期间提供basename,因为它们实际上都是来自同一custom_user模型的。

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')

答案 1 :(得分:2)

Django-rest-framework的路由器尝试通过其模型/查询集标识视图集,因为两个视图集都使用相同的模型,因此很可能会混淆。 来自documentation

  

如果未设置,则将基于视图集的queryset属性自动生成基本名称。请注意,如果视图集不包含queryset属性,则在注册视图集时必须设置基本名称。

尝试向路由器提供basename

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')