django-vue3-admin-backend/crud_book/views.py
2025-10-23 01:10:28 +08:00

176 lines
6.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Create your views here.
import os
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework import status, viewsets, serializers
from rest_framework.permissions import IsAuthenticated
from crud_book.models import CrudBookModel, ReadingProgress
from crud_book.serializers import (
CrudBookModelSerializer,
CrudBookModelCreateUpdateSerializer,
ReadingProgressSerializer
)
from dvadmin.utils.viewset import CustomModelViewSet
class CrudBookModelViewSet(CustomModelViewSet):
"""
list:查询
create:新增
update:修改
retrieve:单例
destroy:删除
"""
queryset = CrudBookModel.objects.all()
serializer_class = CrudBookModelSerializer
create_serializer_class = CrudBookModelCreateUpdateSerializer
update_serializer_class = CrudBookModelCreateUpdateSerializer
@action(detail=True, methods=['get'])
def file(self, request, pk=None):
"""
获取图书文件信息或直接下载文件
"""
try:
# 先检查图书是否存在
try:
book = self.get_object()
except Exception as e:
return Response(
{'code': 404, 'msg': f'图书不存在: {str(e)}'},
status=status.HTTP_404_NOT_FOUND
)
# 检查图书是否有文件
if not book.file:
return Response(
{'code': 404, 'msg': '该图书没有上传文件'},
status=status.HTTP_404_NOT_FOUND
)
# 检查文件是否实际存在于文件系统
if not os.path.exists(book.file.path):
return Response(
{'code': 404, 'msg': '文件在服务器上不存在'},
status=status.HTTP_404_NOT_FOUND
)
# 返回文件URL信息作为标准格式
file_url = request.build_absolute_uri(book.file.url)
return Response({
'code': 2000,
'data': {
'file_url': file_url,
'file_type': book.file_type or 'epub',
'filename': os.path.basename(book.file.name)
},
'msg': '成功'
}, status=status.HTTP_200_OK)
except Exception as e:
return Response(
{'code': 500, 'msg': f'服务器错误: {str(e)}'},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
class ReadingProgressViewSet(viewsets.ModelViewSet):
"""
阅读进度管理
"""
queryset = ReadingProgress.objects.all()
serializer_class = ReadingProgressSerializer
permission_classes = [IsAuthenticated]
def get_queryset(self):
"""只返回当前用户的阅读进度"""
return ReadingProgress.objects.filter(user=self.request.user)
def create(self, request, *args, **kwargs):
"""创建或更新阅读进度"""
# 检查用户是否已认证
if not request.user.is_authenticated:
return Response(
{'code': 401, 'msg': '用户未登录,无法保存阅读进度'},
status=status.HTTP_401_UNAUTHORIZED
)
# 获取序列化器
serializer = self.get_serializer(data=request.data)
try:
# 验证数据
serializer.is_valid(raise_exception=True)
# 尝试查找现有记录
try:
book_id = request.data.get('book_id')
book = CrudBookModel.objects.get(id=book_id)
# 使用update_or_create而不是普通的save避免重复记录
progress, created = ReadingProgress.objects.get_or_create(
user=request.user,
book=book
)
# 更新字段
progress.location = request.data.get('location', '')
progress.progress = request.data.get('progress', 0)
progress.creator = request.user # 确保设置creator
progress.save()
# 返回更新后的序列化数据,包装成前端期望的格式
serializer = self.get_serializer(progress)
return Response(
{'code': 2000, 'data': serializer.data, 'msg': '成功'},
status=status.HTTP_200_OK
)
except CrudBookModel.DoesNotExist:
return Response(
{'code': 404, 'msg': f'ID为{book_id}的图书不存在'},
status=status.HTTP_404_NOT_FOUND
)
except serializers.ValidationError as e:
# 返回序列化验证错误
return Response(
{'code': 400, 'msg': str(e.detail)},
status=status.HTTP_400_BAD_REQUEST
)
except Exception as e:
# 记录错误
import logging
logger = logging.getLogger(__name__)
logger.error(f'保存阅读进度失败: {str(e)}')
return Response(
{'code': 500, 'msg': f'保存阅读进度失败: {str(e)}'},
status=status.HTTP_500_INTERNAL_SERVER_ERROR
)
@action(detail=False, methods=['get'])
def by_book(self, request):
"""根据图书ID获取阅读进度"""
book_id = request.query_params.get('book_id')
if not book_id:
return Response(
{'code': 400, 'msg': '缺少book_id参数'},
status=status.HTTP_400_BAD_REQUEST
)
try:
progress = ReadingProgress.objects.get(
user=request.user,
book_id=book_id
)
serializer = self.get_serializer(progress)
return Response(
{'code': 2000, 'data': serializer.data, 'msg': '成功'},
status=status.HTTP_200_OK
)
except ReadingProgress.DoesNotExist:
return Response(
{'code': 2000, 'data': {'location': '', 'progress': 0}, 'msg': '未找到阅读进度记录'},
status=status.HTTP_200_OK
)