我在同一URL上有2个视图集,一个用于创建和列出视图,另一个用于检索更新和销毁视图。遵循以下Viewset代码
class UserViewSet(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
"""
retrieves user accounts
"""
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (AllowAny,)
class UserCreateViewSet(mixins.CreateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet):
"""
Creates user accounts
"""
queryset = User.objects.all()
serializer_class = CreateUserSerializer
permission_classes = (AllowAny,)
def list(self, request, *args, **kwargs):
email = self.request.query_params.get('email', None)
phone_no = self.request.query_params.get('phone_no', None)
if email is not None:
queryset = User.objects.filter(email=email)
elif phone_no is not None:
queryset = User.objects.filter(phone_no=phone_no)
else:
queryset = User.objects.all()
return super(UserCreateViewSet, self).list(request, *args, **kwargs)
这是我的网址配置:
router = DefaultRouter()
router.register(r'users', UserCreateViewSet)
router.register(r'users', UserViewSet)
router.register(r'advertisement', AdvertisementCreateViewSet)
router.register(r'advertisement', AdvertisementViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api-token-auth/', CustomAuthToken.as_view()),
path('api-token-auth/verify-otp', VerifyTokenView.as_view()),
path('api-token-auth/verify-email', VerifyEmailView.as_view()),
path('api/v1/admin/login', LoginAdminUser.as_view()),
path('api/v1/user/reset-password/', ResetPasswordView.as_view()),
url('api/v1/user/(?P<id>.+)/changePassword', ChangePasswordView.as_view())
path('api/v1/', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
re_path(r'^$', RedirectView.as_view(url=reverse_lazy('api-root'), permanent=False)),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
广告ViewSet在不同的模型上可以做完全相同的事情,并且效果很差。 但是在UserViewSet中却没有。我尝试比较两个视图集的代码,它们完全相同。...
答案 0 :(得分:0)
我认为您误解了ViewSets
的工作方式。单个ViewSet
可以包含您希望模型使用的全部逻辑。我认为在您注册路线时会发生冲突,导致ViewSet
之一不起作用。
您应该将所有逻辑合并到一个ViewSet
中:
class UserViewSet(
mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet,
):
queryset = User.objects.all()
permission_classes = (AllowAny,)
def get_serializer_class(self):
"""Return the serializer class given the action"""
action = self.action
if self.action == 'create' or self.action == 'list':
return CreateUserSerializer
else:
return UserSerializer
def list(self, request, *args, **kwargs):
email = self.request.query_params.get('email', None)
phone_no = self.request.query_params.get('phone_no', None)
if email is not None:
queryset = User.objects.filter(email=email)
elif phone_no is not None:
queryset = User.objects.filter(phone_no=phone_no)
else:
queryset = User.objects.all()
return super().list(request, *args, **kwargs)
关于我的示例的一些评论:
get_serializer_class
,因为我看到您的视图集上有两个不同的序列化器。但是,我很确定您可以使用Serializer
字段中的read_only
/write_only
options做您想要的事情。list
视图中,您正在实现一些过滤逻辑。您可以使用django-filter
更轻松地执行此操作,而不必重载list
方法。