Django GenericViewSet: не может создавать собственные маршруты - PullRequest
0 голосов
/ 06 июня 2019

Я изо всех сил пытаюсь понять, как в Django работают родовые представления на основе классов. Документация не охватывает общие виды в деталях. Я создал пользовательский @list_route, но, кажется, нет способа его назвать. Вот код:

вид:

class AnalyticsViewSet(viewsets.GenericViewSet):
    queryset = models.BookingAnalytics.objects.exclude(status=booking_constants.BookingState.deleted)
    permission_classes = [DRYPermissions, ]
    filter_backends = [DjangoFilterBackend, ]
    filter_class = filters.AnalyticsFilter
    serializer_class = serializers.AnalyticsDetailSerializer
    serializer_classes = {}

    def list(self, request, *args, **kwargs):
        if not request.user.is_role_admin:
            raise exc.PermissionDenied()

        queryset = self.get_queryset()

        filtered_queryset = self.filter_queryset(queryset)

        data = {
            'stats': {
                ....
            }
        }

        return response.Ok(data)

    @list_route(methods=['POST'], url_path='export')
    def export(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        filtered_queryset = self.filter_queryset(queryset)

        recipients = []

        if 'recipients' in request.data:
            recipients = request.data['recipients']

        ....

        return response.NoContent()

Модель:

class BookingAnalytics(UUIDModel, TimeStampedModel):
    ...

    class Meta:
        verbose_name = _('booking analytic')
        verbose_name_plural = _('booking analytics')
        ordering = ('-booking_date', '-created',)

    def __str__(self):
        return self.uuid

    @staticmethod
    @authenticated_users
    def has_read_permission(request) -> bool:
        return request.user.is_role_admin or request.user.is_role_client

    @staticmethod
    @authenticated_users
    def has_write_permission(request) -> bool:
        return request.user.is_role_admin or request.user.is_role_client

    @staticmethod
    @authenticated_users
    def has_object_list_permission(request) -> bool:
        return request.user.is_role_admin

    @authenticated_users
    def has_object_export_permission(self, request) -> bool:
        return request.user.is_role_admin

Здесь маршрут по умолчанию list работает просто отлично. Однако маршрут export вообще не вызывается.

Что мне не хватает? enter image description here

enter image description here

В отличие от этого, у меня есть другой набор представлений с множеством пользовательских маршрутов, и они отлично работают:

class BookingViewSet(
    MultipleSerializerMixin,
    mixins.CreateModelMixin,
    mixins.RetrieveModelMixin,
    mixins.UpdateModelMixin,
    viewsets.GenericViewSet
):
    lookup_field = 'uuid'
    queryset = models.Booking.objects.all()
    permission_classes = [DRYPermissions, ]
    filter_backends = [filters.BookingFilterBackend, filters.BookingExportFilterBackend, DjangoFilterBackend, ]
    filter_class = filters.BookingFilter
    pagination_class = BookingViewSetPagination
    serializer_class = serializers.BookingDetailSerializer

    serializer_classes = {...}

    ....

    @list_route(methods=['POST'], url_path='export-bookings')
    def export_bookings(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        filtered_queryset = self.filter_queryset(queryset)

        recipients = []

        if 'recipients' in request.data:
            recipients = request.data['recipients']

        ....

        return response.NoContent()

1 Ответ

0 голосов
/ 07 июня 2019

Вот как я в итоге заставляю это работать.

views.py

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def export(request, format=None):
    qs = models.BookingAnalytics.objects.all()

    filtered_queryset = filters.AnalyticsFilter(request.GET, queryset=qs)

    recipients = []

    if 'recipients' in request.data:
        recipients = request.data['recipients']
    ....

    return response.NoContent()

urls.py

...
    url(r'^export$', export, name='export'),
...
...