Инспекция кода: Реализация GET запроса в Django REST Framework

Учусь писать "красивый" хорошо читаемый и технологичный код. По этому буду рад комментариям и по оформлению в том числе.

Задача:
По тз аутентифицированному клиенту должны возвращаться n-ные поля моделей.

Если запрос приходит без PrimaryKey
urlpath('users/', ... т.е. *GET http://127.0.0.1:8000/api/v1/users/*,\ то рендерятся поля всех моделей из бд.

Если же РК был передан и он существует,
url path('users/<str:pk>/, ...' т.е. *GET http://127.0.0.1:8000/api/v1/users/2*\ то отдается конкретная модель, иначе клиент получает сообщение о несуществующем ключе

Вопросы:

  1. На сколько такой способ корректен(использовать одну функцию для двух, пусть похожих, но но все же разных GET-запросов)?
  2. На сколько читабельна такая конструкция try-except, на сколько она корректно составлена?
  3. Как в целом выглядит этот код?
**views.py**

class UserViewSet(ListAPIView):

    # Allow only authenticated users to access this urls
    permission_classes = [IsAuthenticated, ]

    def get(self, request, **kwargs):

        '''
        Handles `CustomUser` objects into JSON and sends to the client.
        -If function did not recieve primary_key into **kwargs, it serializes fields of all CustomUser models.
        -If function recieved primary_key and it is exists, then serializes this model, otherwise tells that primary_key recived does not exists.
        '''

        try:
            pk = kwargs['pk']
            try:
                queryset = CustomUser.objects.get(id=pk)
            except:
                return Response({
                        "message": f"User with primary_key `{pk}`does not exists."},
                        status=status.HTTP_404_NOT_FOUND
                    )
        except:
            queryset = CustomUser.objects.all()
            serializer = ReadOnlyUserSerializer(queryset.values(), many=True)
        else:
            serializer = ReadOnlyUserSerializer(queryset, many=False)

        return Response(serializer.data, status=status.HTTP_200_OK)



Ответы (1 шт):

Автор решения: 5c0rp

Как по мне то ListAPIView не совсем подходит для отображения конкретной модели. Советую вам глянуть в сторону ModelViewSet. Этот класс подойдет для чтения, создания, обновления и удаления объекта. Он так же поддерживает возможности схожие с ListAPIView для отображения списка объектов.

Код выглядит довольно кратко

from rest_framework.viewsets import ModelViewSet
from rest_framework.router import SimpleRouter
from ... import ваш сериализатор

class UserViewSet(ModelViewSet):
    permission_classes = [IsAuthenticated, ]  # Эту часть можно упустить если в settings.py указать настройку для DRF
    queryset = CustomUser.objects.all()
    serializer_class = ваш сериализатор

router = SimpleRouter()
router.register('users', UserViewSet)
urlpatterns = router.urls

Если вам нужно реализовать только чтение то можно заменить ModelViewSet на ReadOnlyModelViewSet.

→ Ссылка