Django中指定div定时局部刷新异常问题排查
Hey there! Let's work through your Django sensor data refresh issues together. I’ve dealt with similar periodic update problems before, so let’s break down what’s going wrong and fix it step by step.
First, let's recap your setup: you're sending sensor data to a Django model via POST every 5 seconds from a Wi-Fi module, and you want a specific <div> on your page to refresh every 10 seconds to show the latest data. But three different attempts led to weird issues—let's unpack each problem first, then build a reliable solution.
Why Your Previous Attempts Failed
First scheme:
testdiv disappears after first refresh
Chances are you were replacing the entire div instead of its inner content (e.g., usingreplaceWith()instead ofhtml()), or the partial HTML you returned didn’t include the<div id="test">wrapper. Without that ID, subsequent AJAX calls can’t find the element to update.Second scheme: div vanishes after two GET requests
This is usually caused by duplicate timers (accidentally callingsetInterval()multiple times) or an error in your AJAX error handler that removes/hides the div. If one request fails, your code might be wiping out the element instead of showing an error message.Third scheme: requests work but data doesn’t sync
Django caches view responses by default, so if your view wasn’t explicitly told to skip caching, you’d get stale data. Or maybe your view wasn’t re-querying the database for the latest entries (e.g., using a cached queryset instead of fetching fresh data each time).
A Reliable Step-by-Step Solution
Let’s build this properly, with separate views for POST data handling, partial HTML rendering, and a clean JS refresh loop.
1. Update Your views.py
We need three views: one to accept sensor POST data, one to return the fresh sensor data as a partial HTML snippet, and one for the main page. We’ll disable caching on the partial view to ensure fresh data every time.
from django.shortcuts import render, HttpResponse from .models import SensorData from django.views.decorators.cache import never_cache from django.views.decorators.csrf import csrf_exempt import json # Handle POST requests from your Wi-Fi module @csrf_exempt # Remove this in production and add proper CSRF/auth def sensor_post(request): if request.method == "POST": # Parse incoming data (adjust based on your module's format) sensor_data = json.loads(request.body) # Create a new SensorData entry (match your model fields) SensorData.objects.create( temperature=sensor_data.get("temperature"), humidity=sensor_data.get("humidity"), timestamp=sensor_data.get("timestamp") # Or let Django auto-set this ) return HttpResponse("Data received", status=200) return HttpResponse("Invalid request method", status=405) # Return fresh sensor data as a partial HTML snippet (no caching!) @never_cache def sensor_data_partial(request): # Fetch the latest sensor entry (adjust query for your needs) latest_reading = SensorData.objects.order_by("-timestamp").first() # Render just the content for the test div return render(request, "partial_sensor.html", {"reading": latest_reading}) # Main page view def test_dashboard(request): return render(request, "test.html")
2. Configure urls.py
Map the views to URLs so AJAX can reach them:
from django.urls import path from . import views urlpatterns = [ path("test/", views.test_dashboard, name="test_dashboard"), path("sensor/post/", views.sensor_post, name="sensor_post"), path("sensor/partial/", views.sensor_data_partial, name="sensor_data_partial"), ]
3. Create a Partial Template (partial_sensor.html)
This template holds only the content that needs refreshing, wrapped in the test div to preserve the ID:
<div id="test"> {% if reading %} <p>Temperature: {{ reading.temperature }}°C</p> <p>Humidity: {{ reading.humidity }}%</p> <p>Last Updated: {{ reading.timestamp }}</p> {% else %} <p>No sensor data received yet</p> {% endif %} </div>
4. Fix the Main Template (test.html)
Use jQuery to safely refresh the div’s content every 10 seconds, with error handling that doesn’t delete the element:
<!DOCTYPE html> <html> <head> <title>Sensor Dashboard</title> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> </head> <body> <h1>Real-Time Sensor Data</h1> <!-- Initial load of the sensor data partial --> {% include "partial_sensor.html" %} <script> // Function to refresh the sensor data function refreshSensorData() { $.ajax({ url: "{% url 'sensor_data_partial' %}", type: "GET", success: function(response) { // Replace ONLY the inner content of the test div $("#test").html($(response).html()); }, error: function(xhr, status, error) { console.error("Refresh failed:", error); // Show an error message without deleting the div $("#test").html("<p>Failed to load data. Retrying...</p>"); } }); } // Run on page load, then every 10 seconds $(document).ready(function() { refreshSensorData(); setInterval(refreshSensorData, 10000); // 10000ms = 10s }); </script> </body> </html>
Quick Checks to Ensure It Works
- Test the POST endpoint: Use curl or Postman to send a test POST request to
/sensor/post/and confirm a new entry is added to yourSensorDatamodel. - Verify caching is disabled: Check the response headers for the partial view—you should see
Cache-Control: max-age=0, no-cache, no-store, must-revalidate. - Check for duplicate timers: Make sure
setInterval()is only called once (insidedocument.ready), not multiple times.
Bonus: For Production
- Remove
@csrf_exempt: Add a CSRF token to your Wi-Fi module’s POST requests, or use token-based authentication (like OAuth2) for secure data submission. - Consider WebSockets: If you need near-real-time updates instead of 10-second polling, use Django Channels to push data to the page instantly when a new sensor reading arrives.
内容的提问来源于stack exchange,提问作者Parth Jeet

