Django Rest Framework: два набора для одного маршрутизатора - PullRequest
0 голосов
/ 10 октября 2019

Я хочу иметь ДВА РАЗНЫХ представления (например, один реализует только метод GET, другой реализует только метод POST), но который будет иметь тот же URL: GET /tournament/ - возвращает конкретный объект модели Tournament;POST /tournament/ - создать объект модели Tournament.

Но важно, чтобы они имели одинаковый URL /tournament/!

Я пробовал что-то вроде этого:

models.py

class Tournament(Model):
    ...

viewsets.py

class PublicTournamentEndpoint(
    mixins.RetrieveModelMixin,
    mixins.ListModelMixin,
    viewsets.GenericViewSet
):
    queryset = Tournament.objects.all()
    authentication_classes = []  # empty!

class PrivateTournamentEndpoint(
    mixins.CreateModelMixin,
    viewsets.GenericViewSet
):
    queryset = Tournament.objects.all()
    authentication_classes = ['SomeAuthBackend']  # not empty!

routers.py

class TournamentRouter(SimpleRouter):
    routes = [
        Route(
            url=r'^{prefix}/tournament/$',
            mapping={
                'get': 'retrieve',
                'post': 'create',
            },
            name='{basename}',
            detail=True,
            initkwargs={},
        ),

urls.py

tournament_router = TournamentRouter()
tournament_router.register(
    'tournaments',
    PublicTournamentEndpoint,
    basename='tournaments',
)

tournament_router.register(
    'tournaments',
    PrivateTournamentEndpoint,
    basename='tournaments',
)

urlpatterns += tournament_router.urls

Но мойurlpatterns имеет следующие значения:

[
    <URLPattern '^tournaments/tournament/$' [name='tournaments']>, 
    <URLPattern '^tournaments/tournament/$' [name='tournaments']>
]

и поэтому, когда я отправляю запрос POST /tournament/, я получаю следующую ошибку:

405 "Method \"POST\" not allowed."

, поскольку первый URL-адрес совпадения не имеетметод POST, но только GET. Как я могу решить эту проблему?

Спасибо!

1 Ответ

1 голос
/ 10 октября 2019

Вы не можете назвать 2 просмотра для 1 URL. Похоже, вы хотите, чтобы только конкретный пользователь, имеющий разрешение SomeAuthBackend, мог создавать новые Tournament, если это так, вы можете немного настроить свой класс разрешений, чтобы проверять разрешение только для POST запросов, например:

from rest_framework import permissions

class SomeAuthBackend(permissions.BasePermission):
    protected_methods = ['POST',]
    def has_permission(self, request, view):
        if request.method in self.protected_methods:
            # Check permission here

        return True


class TournamentEndpoint(
    mixins.CreateModelMixin,
    mixins.RetrieveModelMixin,
    mixins.ListModelMixin,
    viewsets.GenericViewSet
):
    queryset = Tournament.objects.all()
    authentication_classes = [SomeAuthBackend, ]  # empty!

При этом другой метод все еще работает, но когда пользователь отправляет запрос POST, он должен пройти проверку разрешения на SomeAuthBackend.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...