我将我的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格式的已过滤学习者列表。
非常感谢您的帮助。
答案 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')