Files
chunyu_project/apidirectory/views.py
T

158 lines
5.5 KiB
Python

from adrf.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import AllowAny, IsAuthenticated
from django.http import JsonResponse
from django.db.models import Count
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from .models import ApiCategory, ApiItem, ApiFavorite
from .serializers import ApiCategorySerializer, ApiItemSerializer
class CategoryListView(APIView):
permission_classes = [AllowAny]
@swagger_auto_schema(
operation_summary='获取API分类列表',
operation_description='获取所有API分类及其关联的API数量',
tags=['API接口大全'],
responses={200: '成功'}
)
async def get(self, request):
categories = [c async for c in ApiCategory.objects.prefetch_related('items').all()]
serializer = ApiCategorySerializer(categories, many=True)
return JsonResponse({
'code': 200,
'message': 'success',
'data': serializer.data
})
class ApiItemListView(APIView):
permission_classes = [AllowAny]
@swagger_auto_schema(
operation_summary='获取API列表',
operation_description='获取API列表,支持分类筛选、搜索、排序',
tags=['API接口大全'],
manual_parameters=[
openapi.Parameter('category_id', openapi.IN_QUERY, description='分类ID', type=openapi.TYPE_INTEGER),
openapi.Parameter('search', openapi.IN_QUERY, description='搜索关键词', type=openapi.TYPE_STRING),
openapi.Parameter('ordering', openapi.IN_QUERY, description='排序字段', type=openapi.TYPE_STRING),
],
responses={200: '成功'}
)
async def get(self, request):
category_id = request.query_params.get('category_id')
search = request.query_params.get('search', '')
ordering = request.query_params.get('ordering', '')
items = ApiItem.objects.select_related('category').annotate(
annotated_favorites_count=Count('favorites')
).filter(is_enabled=True)
if category_id:
items = items.filter(category_id=category_id)
if search:
items = items.filter(name__icontains=search) | items.filter(description__icontains=search)
if ordering:
if ordering == '-favorites_count':
items = items.order_by('-annotated_favorites_count')
elif ordering == 'favorites_count':
items = items.order_by('annotated_favorites_count')
else:
items = items.order_by(ordering)
else:
items = items.order_by('sort_order', '-created_at')
item_list = [x async for x in items]
serializer = ApiItemSerializer(item_list, many=True, context={'request': request})
return JsonResponse({
'code': 200,
'message': 'success',
'data': serializer.data
})
class ApiItemDetailView(APIView):
permission_classes = [AllowAny]
@swagger_auto_schema(
operation_summary='获取API详情',
operation_description='获取单个API的详细信息',
tags=['API接口大全'],
responses={200: '成功'}
)
async def get(self, request, pk):
try:
item = await ApiItem.objects.select_related('category').aget(pk=pk, is_enabled=True)
serializer = ApiItemSerializer(item, context={'request': request})
return JsonResponse({
'code': 200,
'message': 'success',
'data': serializer.data
})
except ApiItem.DoesNotExist:
return JsonResponse({
'code': 404,
'message': 'API不存在',
'data': None
}, status=status.HTTP_404_NOT_FOUND)
class FavoriteToggleView(APIView):
permission_classes = [IsAuthenticated]
@swagger_auto_schema(
operation_summary='切换API收藏状态',
operation_description='收藏或取消收藏API接口',
tags=['API接口大全'],
responses={200: '成功'}
)
async def post(self, request, pk):
try:
api_item = await ApiItem.objects.aget(pk=pk, is_enabled=True)
except ApiItem.DoesNotExist:
return JsonResponse({
'code': 404,
'message': 'API不存在',
'data': None
}, status=status.HTTP_404_NOT_FOUND)
fav, created = await ApiFavorite.objects.aget_or_create(user=request.user, api_item=api_item)
if not created:
await fav.adelete()
is_favorited = False
else:
is_favorited = True
favorites_count = await ApiFavorite.objects.filter(api_item=api_item).acount()
return JsonResponse({
'code': 200,
'message': 'success',
'data': {
'id': api_item.id,
'is_favorited': is_favorited,
'favorites_count': favorites_count
}
})
def api_directory_index(request):
return JsonResponse({
'code': 200,
'message': 'API Directory index',
'data': {
'endpoints': {
'categories': '/api/apidirectory/categories/',
'items': '/api/apidirectory/items/',
'item_detail': '/api/apidirectory/items/{id}/',
'favorite_toggle': '/api/apidirectory/items/{id}/favorite/',
}
}
})