You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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}&current_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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 11:47:08