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

Django中实现页面定时获取新文章并更新的技术问询

嘿,这个实时更新文章的需求很典型,我来给你梳理一套完整的实现方案,分后端(Django)和前端两部分来讲,保证你能快速落地!

后端实现(Django部分)

首先咱们先把后端的API接口搭起来,用来处理前端的轮询请求:

1. 确保Article模型的status字段配置正确

你的Article模型里已经有status字段了,记得把默认值设为1,最好加上选项让管理后台更直观:

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    # status=1展示,status=0不展示,默认值1
    status = models.IntegerField(
        default=1,
        choices=[(0, '不展示'), (1, '展示')]
    )
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-created_at']  # 按创建时间倒序,最新的在前

2. 写一个处理轮询的视图函数

这个视图要接收前端传的last_shown_id参数,返回所有status=1且ID大于last_shown_id的新文章(用ID过滤简单直接,你也可以换成创建时间来判断):

from django.http import JsonResponse
from .models import Article

def get_new_articles(request):
    # 获取前端传的最后展示的文章ID,默认0(第一次请求时没有这个参数)
    last_shown_id = request.GET.get('last_shown_id', 0)
    # 过滤出符合条件的文章,只返回需要的字段(按需调整)
    new_articles = Article.objects.filter(
        status=1,
        id__gt=last_shown_id
    ).values('id', 'title', 'content')
    # 转成列表返回JSON格式
    return JsonResponse(list(new_articles), safe=False)

3. 配置URL路由

把上面的视图映射到一个API路径,比如在你的app的urls.py里:

from django.urls import path
from . import views

urlpatterns = [
    # 其他业务路由...
    path('api/get-new-articles/', views.get_new_articles, name='get_new_articles'),
]
前端实现(AJAX轮询)

接下来写前端的逻辑,实现每隔N秒请求一次后端,自动更新页面内容:

1. 页面结构

先准备一个展示文章的容器,别忘了加上Django要求的CSRF令牌(否则AJAX请求会被拒绝):

<!-- 文章展示容器 -->
<div id="articles-container">
    <!-- 初始加载的文章可以用Django模板循环渲染 -->
    {% for article in initial_articles %}
        <div class="article" data-id="{{ article.id }}">
            <h3>{{ article.title }}</h3>
            <p>{{ article.content }}</p>
        </div>
    {% endfor %}
</div>

<!-- Django的CSRF令牌,必须添加 -->
{% csrf_token %}

2. JavaScript轮询逻辑

用原生JS的fetch API来实现,逻辑清晰易维护:

// 获取CSRF令牌的值
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
// 保存最后展示的文章ID,初始值从页面已有的文章里取最大的ID
let lastShownId = 0;
const articlesContainer = document.getElementById('articles-container');
const existingArticles = articlesContainer.querySelectorAll('.article');
if (existingArticles.length > 0) {
    lastShownId = parseInt(existingArticles[existingArticles.length - 1].dataset.id);
}

// 定义获取新文章的函数
function fetchNewArticles() {
    fetch(`/api/get-new-articles/?last_shown_id=${lastShownId}`, {
        method: 'GET',
        headers: {
            'X-CSRFToken': csrfToken,  // 带上CSRF令牌
            'Content-Type': 'application/json'
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.length > 0) {
            // 把新文章添加到容器末尾
            data.forEach(article => {
                const articleDiv = document.createElement('div');
                articleDiv.className = 'article';
                articleDiv.dataset.id = article.id;
                articleDiv.innerHTML = `
                    <h3>${article.title}</h3>
                    <p>${article.content}</p>
                `;
                articlesContainer.appendChild(articleDiv);
                // 更新最后展示的文章ID为最新的那个
                lastShownId = article.id;
            });
        }
    })
    .catch(error => {
        console.error('获取新文章失败:', error);
        // 可以在这里加简单的重试逻辑,避免一次失败就停更
    });
}

// 设置定时器,每隔N秒调用一次(比如N=5就是5秒)
const pollInterval = 5 * 1000; // 单位是毫秒
setInterval(fetchNewArticles, pollInterval);

// 页面加载完成后先调用一次,不用等N秒才更新
window.addEventListener('load', fetchNewArticles);
一些优化小建议
  • 如果文章更新频率不高,可以用**长轮询(Long Polling)**代替普通轮询:后端收到请求后,如果没有新文章就不立即返回,而是等待有新文章或者超时才响应,能大幅减少请求次数,节省服务器资源。
  • 可以加个标签页监听逻辑:用户切到其他标签页时暂停轮询,切回来再恢复,节省浏览器资源。
  • 如果文章数量很大,后端可以加分页限制,比如每次最多返回10条新文章,避免一次返回过多数据影响性能。

内容的提问来源于stack exchange,提问作者Rustam Rakhimov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:05:46