Ctrl K
ComunidadGuías…

files/views/categories.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
from django.conf import settings
from django.db.models import Q
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.response import Response
from rest_framework.settings import api_settings
from rest_framework.views import APIView

from ..methods import is_mediacms_editor
from ..models import Category, Tag
from ..serializers import CategorySerializer, TagSerializer


def visible_categories(request, show_lms=None):
    """Categories the requesting user is allowed to see

    One place where category visibility is decided, so listing a category and retrieving
    one by uid cannot disagree.
    """

    if show_lms is None:
        show_lms = getattr(settings, 'SHOW_LMS_COURSES_IN_CATEGORIES', True)

    categories = Category.objects.prefetch_related("user")

    if not show_lms:
        categories = categories.filter(is_lms_course=False)

    if not is_mediacms_editor(request.user):
        visible = Q(is_rbac_category=False)
        if getattr(settings, 'USE_RBAC', False) and request.user.is_authenticated:
            member_of = request.user.get_rbac_categories_as_member().values_list("pk", flat=True)
            visible |= Q(pk__in=member_of)
        categories = categories.filter(visible)

    return categories


class CategoryList(APIView):
    """List categories"""

    @swagger_auto_schema(
        manual_parameters=[
            openapi.Parameter(name='q', type=openapi.TYPE_STRING, in_=openapi.IN_QUERY, description='Search by title and description'),
        ],
        tags=['Categories'],
        operation_summary='Lists Categories',
        operation_description='Lists all categories',
        responses={
            200: openapi.Response('response description', CategorySerializer),
        },
    )
    def get(self, request, format=None):
        categories = visible_categories(request).order_by("title")
        query = request.GET.get("q", "").strip()
        if query:
            categories = categories.filter(Q(title__icontains=query) | Q(description__icontains=query))

        serializer = CategorySerializer(categories, many=True, context={"request": request})
        ret = serializer.data
        return Response(ret)


class CategoryDetail(APIView):
    """Get a single category by uid"""

    @swagger_auto_schema(
        manual_parameters=[],
        tags=['Categories'],
        operation_summary='Get Category',
        operation_description='Get a single category by uid',
        responses={
            200: openapi.Response('response description', CategorySerializer),
            404: openapi.Response('category not found'),
        },
    )
    def get(self, request, uid, format=None):
        category = visible_categories(request).filter(uid=uid).first()
        if not category:
            return Response({"detail": "not found"}, status=status.HTTP_404_NOT_FOUND)

        serializer = CategorySerializer(category, context={"request": request})
        return Response(serializer.data)


class CategoryListContributor(APIView):
    """List LMS courses where the user has contributor access"""

    @swagger_auto_schema(
        tags=['Categories'],
        operation_summary='Lists LMS courses for Contributors',
        operation_description='Lists LMS courses where the user has contributor access',
        responses={
            200: openapi.Response('response description', CategorySerializer),
        },
    )
    def get(self, request, format=None):
        if not request.user.is_authenticated:
            return Response([])

        categories = request.user.get_rbac_categories_as_contributor().filter(is_lms_course=True)

        serializer = CategorySerializer(categories.order_by("title"), many=True, context={"request": request})
        return Response(serializer.data)


class TagList(APIView):
    """List tags"""

    @swagger_auto_schema(
        manual_parameters=[
            openapi.Parameter(name='page', type=openapi.TYPE_INTEGER, in_=openapi.IN_QUERY, description='Page number'),
            openapi.Parameter(name='q', type=openapi.TYPE_STRING, in_=openapi.IN_QUERY, description='Search by title'),
        ],
        tags=['Tags'],
        operation_summary='Lists Tags',
        operation_description='Paginated listing of all tags',
        responses={
            200: openapi.Response('response description', TagSerializer),
        },
    )
    def get(self, request, format=None):
        tags = Tag.objects.filter().order_by("-media_count")
        query = request.GET.get("q", "").strip()
        if query:
            tags = tags.filter(title__icontains=query)
        pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
        paginator = pagination_class()
        page = paginator.paginate_queryset(tags, request)
        serializer = TagSerializer(page, many=True, context={"request": request})
        return paginator.get_paginated_response(serializer.data)