Django项目中PDF阅读最后位置保存功能实现问题
实现Django用户阅读进度记忆功能
1. 新增阅读进度存储模型
在你的app的models.py里添加模型,关联用户和书籍,确保每个用户每本书只有一条进度记录:
from django.db import models from django.contrib.auth.models import User from .models import Book # 假设你已定义书籍模型Book class ReadingProgress(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) book = models.ForeignKey(Book, on_delete=models.CASCADE) current_page = models.IntegerField(default=1) # 可根据需求换成章节ID/滚动百分比 updated_at = models.DateTimeField(auto_now=True) class Meta: unique_together = ('user', 'book') # 避免同一用户同一书多条进度
执行数据库迁移:
python manage.py makemigrations python manage.py migrate
2. 编写进度保存接口
在views.py里写一个视图,处理前端传来的进度数据,自动创建或更新进度记录:
from django.http import JsonResponse from django.views.decorators.http import require_POST from django.contrib.auth.decorators import login_required from .models import ReadingProgress, Book @login_required @require_POST def save_reading_progress(request): book_id = request.POST.get('book_id') current_page = request.POST.get('current_page') if not book_id or not current_page: return JsonResponse({'status': 'error', 'message': '缺少必要参数'}, status=400) try: book = Book.objects.get(id=book_id) progress, created = ReadingProgress.objects.get_or_create( user=request.user, book=book, defaults={'current_page': int(current_page)} ) if not created: progress.current_page = int(current_page) progress.save() return JsonResponse({'status': 'success'}) except Book.DoesNotExist: return JsonResponse({'status': 'error', 'message': '书籍不存在'}, status=404)
在urls.py添加对应路由:
from django.urls import path from . import views urlpatterns = [ # 其他路由... path('save-progress/', views.save_reading_progress, name='save_reading_progress'), ]
3. 前端实时提交进度
在阅读页面模板里加入JS,监听用户阅读行为(翻页/滚动),定时或触发事件时提交进度:
<!-- 阅读页面模板 --> <input type="hidden" id="book-id" value="{{ book.id }}"> <script> const bookId = document.getElementById('book-id').value; let currentPage = 1; // 从你的阅读组件获取实际页码 // 监听翻页事件(示例,根据你的组件调整) document.addEventListener('pageChange', function(e) { currentPage = e.detail.page; saveProgress(); }); // 每30秒自动保存一次 setInterval(() => { saveProgress(); }, 30000); function saveProgress() { if (!bookId || !currentPage) return; fetch('{% url "save_reading_progress" %}', { method: 'POST', headers: { 'X-CSRFToken': '{{ csrf_token }}', 'Content-Type': 'application/x-www-form-urlencoded', }, body: `book_id=${bookId}¤t_page=${currentPage}` }) .then(response => response.json()) .catch(error => console.error('保存进度失败:', error)); } </script>
4. 登录后加载历史进度
在进入阅读页面的视图里,读取用户的历史进度,传给模板初始化阅读位置:
from django.shortcuts import render, get_object_or_404 from django.contrib.auth.decorators import login_required from .models import Book, ReadingProgress @login_required def read_book(request, book_id): book = get_object_or_404(Book, id=book_id) initial_page = 1 # 查询用户的历史进度 progress = ReadingProgress.objects.filter(user=request.user, book=book).first() if progress: initial_page = progress.current_page return render(request, 'read_book.html', { 'book': book, 'initial_page': initial_page, })
在阅读页面模板里,用initial_page初始化阅读位置:
<!-- 阅读页面模板 --> <script> const initialPage = {{ initial_page }}; // 调用你的阅读组件跳转到指定页码 yourReadingComponent.goToPage(initialPage); </script>
内容的提问来源于stack exchange,提问作者David Amugune
相关产品推荐
相关产品推荐

