如何在Python项目中实现MongoDB数据实时展示到HTML页面?
需求与现有代码
我正在开发一个Python项目,想要从MongoDB中获取并实时展示数据——新数据一经存入数据库,就立即在HTML表格页面中显示,其余数据可通过刷新页面展示。
现有view.py代码
def datatable_view(request): if request.method =='POST': form = Scraping(request.POST) if form.is_valid(): subject=form.cleaned_data['subject'] #run python code of scraping scrap(subject) #add the products scraped to the database client = pymongo.MongoClient("mongodb://localhost:27017/") # use variable names for db and collection reference db= client["db2"] col = db[subject] products = col.find() context = {'products' : products} #open datatable html and display all the data from database return render(request,'datatable.html', context) return
现有datatable.html代码
<table id="scrap" class="table table-striped table-bordered" style="width:100%"> <tbody> {% for product in products %} <tr> <td> {{ product.Title }} </td> <td> {{ product.Price }} </td> <td> {{ product.Currency }} </td> <td> {{ product.Stars }} </td> <td> {{ product.Orders}} </td> <td> {{ product.Shipcost }} </td> <td> {{ product.Supplier }} </td> <td><a href="{{product.Productlinks }}"> Click here</a></td> </tr> {% endfor %} </tbody> </table>
解决方案
第一步:修复页面刷新获取数据的问题
当前datatable_view仅处理POST请求,GET请求直接返回空,导致刷新页面后无数据。修改视图逻辑,让GET请求也能查询数据库并返回页面:
from django.shortcuts import render from .forms import Scraping import pymongo def datatable_view(request): client = pymongo.MongoClient("mongodb://localhost:27017/") db = client["db2"] context = {} if request.method == 'POST': form = Scraping(request.POST) if form.is_valid(): subject = form.cleaned_data['subject'] scrap(subject) col = db[subject] products = col.find() context['products'] = products context['subject'] = subject # 保存当前查询主题,用于后续实时更新 return render(request, 'datatable.html', context) else: # GET请求时,根据url参数查询对应集合 subject = request.GET.get('subject') if subject: col = db[subject] products = col.find() context['products'] = products context['subject'] = subject form = Scraping() context['form'] = form return render(request, 'datatable.html', context)
同时更新HTML,添加表单(用于提交爬取请求)并完善表格结构:
<!-- 爬取请求表单 --> <form method="POST"> {% csrf_token %} {{ form.as_p }} <button type="submit">爬取并展示数据</button> </form> <table id="scrap" class="table table-striped table-bordered" style="width:100%"> <thead> <tr> <th>标题</th> <th>价格</th> <th>货币</th> <th>星级</th> <th>订单量</th> <th>运费</th> <th>供应商</th> <th>商品链接</th> </tr> </thead> <tbody> {% for product in products %} <tr data-id="{{ product._id|stringformat:'s' }}"> <td> {{ product.Title }} </td> <td> {{ product.Price }} </td> <td> {{ product.Currency }} </td> <td> {{ product.Stars }} </td> <td> {{ product.Orders}} </td> <td> {{ product.Shipcost }} </td> <td> {{ product.Supplier }} </td> <td><a href="{{product.Productlinks }}">点击查看</a></td> </tr> {% endfor %} </tbody> </table>
第二步:实现新数据实时展示
要实现新数据存入后立即显示,推荐两种方案:
方案一:AJAX轮询(简单易实现)
通过定时发送AJAX请求查询新增数据,适合小型项目:
1. 新增API接口返回新增数据
在view.py中添加接口,用于获取指定集合的最新数据:
from django.http import JsonResponse from bson.objectid import ObjectId def get_new_products(request): subject = request.GET.get('subject') if not subject: return JsonResponse({'status': 'error', 'message': '缺少查询主题参数'}, status=400) client = pymongo.MongoClient("mongodb://localhost:27017/") db = client["db2"] col = db[subject] # 获取页面最后一条数据的ID,用于筛选新增数据 last_id = request.GET.get('last_id') if last_id: products = list(col.find({'_id': {'$gt': ObjectId(last_id)}})) else: products = list(col.find()) # 将MongoDB的ObjectId转为字符串,避免JSON序列化失败 for p in products: p['_id'] = str(p['_id']) return JsonResponse({'status': 'success', 'products': products})
在urls.py中添加路由:
from django.urls import path from . import views urlpatterns = [ path('datatable/', views.datatable_view, name='datatable'), path('get-new-products/', views.get_new_products, name='get_new_products'), ]
2. 前端添加轮询逻辑
在datatable.html中添加JavaScript代码,定时调用API并更新表格:
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script> <script> $(document).ready(function() { let subject = "{{ subject }}"; let lastId = ""; // 初始化时获取页面最后一条数据的ID let lastRow = $("#scrap tbody tr:last"); if (lastRow.length > 0) { lastId = lastRow.data('id'); } // 定时查询新增数据的函数 function checkNewProducts() { if (!subject) return; $.ajax({ url: "{% url 'get_new_products' %}", data: { 'subject': subject, 'last_id': lastId }, success: function(response) { if (response.status === 'success' && response.products.length > 0) { let tbody = $("#scrap tbody"); response.products.forEach(function(product) { // 生成新行并添加到表格 let row = `<tr data-id="${product._id}"> <td>${product.Title}</td> <td>${product.Price}</td> <td>${product.Currency}</td> <td>${product.Stars}</td> <td>${product.Orders}</td> <td>${product.Shipcost}</td> <td>${product.Supplier}</td> <td><a href="${product.Productlinks}">点击查看</a></td> </tr>`; tbody.append(row); // 更新最后一条数据的ID lastId = product._id; }); } }, error: function() { console.log('获取新数据失败'); } }); } // 每5秒执行一次查询 setInterval(checkNewProducts, 5000); }); </script>
方案二:WebSocket(高效实时)
如果对实时性要求高(比如数据更新频繁),可以使用Django Channels实现WebSocket通信,监听MongoDB的Change Streams推送新数据。该方案需要配置Redis作为消息中间件,适合中大型项目,配置相对复杂,但实时性远高于轮询。
内容的提问来源于stack exchange,提问作者beatfloraminederecho
相关产品推荐
相关产品推荐

