Django新手求助:Ajax无法接收服务器响应数据
Hey there! Let's work through this issue step by step—since you're a Django newbie, I'll keep things clear and actionable so you can get that dynamic table filling working without page refreshes.
First: Fix Your View to Stream Responses
The problem with your current handle function is that regular HttpResponse waits to send all content at once, which defeats your goal of "gradually filling the table." Instead, you need to use Django's StreamingHttpResponse to send chunks of content as your script processes the file.
Here's a revised version of your handle view (I'll add comments to explain each part):
from django.http import StreamingHttpResponse, HttpResponse import time # Replace this with your actual script calls def handle(request): if request.method == 'POST' and request.FILES.get('uploaded_file'): uploaded_file = request.FILES['uploaded_file'] # This generator function will yield chunks of HTML as processing happens def stream_table_rows(): # Simulate step 1 of your script processing yield '<tr><td>Processing file metadata</td><td>Completed</td></tr>' time.sleep(1) # Replace with your script's actual processing logic # Simulate step 2 yield '<tr><td>Running analysis on file</td><td>Completed</td></tr>' time.sleep(1) # Add as many steps as your script needs yield '<tr><td>Finalizing results</td><td>Completed</td></tr>' # Return the streaming response with the right content type return StreamingHttpResponse(stream_table_rows(), content_type='text/html') # Handle invalid requests return HttpResponse("Invalid request: No file uploaded or wrong method", status=400)
Second: Double-Check Your URL Configuration
Make sure your handle view is mapped correctly in urls.py so your Ajax call can reach it:
from django.urls import path from . import views urlpatterns = [ path('', views.home, name='home'), path('handle-file/', views.handle, name='handle'), # Use a clear URL name ]
Third: Fix Your Ajax to Listen for Streaming Content
Regular Ajax success callbacks only fire once the entire response is received—so you won't get the gradual updates you want. Instead, use the onprogress event to catch chunks of content as they arrive. Also, don't forget Django's CSRF protection!
Here's a sample front-end setup (using jQuery for simplicity):
<!-- Your upload form --> <form id="file-upload-form" method="POST" enctype="multipart/form-data"> {% csrf_token %} <!-- Critical for Django CSRF protection --> <input type="file" name="uploaded_file" required> <button type="submit">Process File</button> </form> <!-- Your target table --> <table id="results-table"> <thead> <tr><th>Processing Step</th><th>Status</th></tr> </thead> <tbody id="table-body"></tbody> </table> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script> $(document).ready(function() { $('#file-upload-form').submit(function(e) { e.preventDefault(); const formData = new FormData(this); $.ajax({ url: '{% url "handle" %}', // Use the URL name from urls.py type: 'POST', data: formData, processData: false, // Required for file uploads contentType: false, // Required for file uploads xhrFields: { // Listen for streaming chunks onprogress: function(e) { if (e.lengthComputable) { // Get the new content that hasn't been added to the table yet const existingContentLength = $('#table-body').html().length; const newChunk = e.responseText.substring(existingContentLength); // Append the new table row if there's content if (newChunk) { $('#table-body').append(newChunk); } } } }, success: function() { alert('All processing completed successfully!'); }, error: function(xhr, status, error) { console.error('Request failed:', error); alert('Oops, something went wrong—check the console for details.'); } }); }); }); </script>
Common Pitfalls to Check
- CSRF Token: Make sure your form includes
{% csrf_token %}—Django will reject POST requests without it. - Browser Network Panel: Use your browser's DevTools → Network tab to inspect the
handle-filerequest. Check if the response is streaming chunks (look at the "Response" tab while the request is in progress). If the response is empty, your script processing isn't yielding content correctly. - Script Integration: Replace the
time.sleep()calls in the view with your actual script logic. Each time your script finishes a step, yield the corresponding HTML table row.
内容的提问来源于stack exchange,提问作者Alex Pinto

