如何在Django2.0中执行多异步方法调用及处理视图异步逻辑?
Hey there! Let's walk through your questions since you're building a small project with Django 2.0 and Python 3.6+, and need to handle parallel REST API calls in your views.
First: Does Django 2.0 Support Async Views?
Straight to the point: No, Django 2.0 does NOT support async views natively. Async view support (with async def) was only introduced in Django 3.1, alongside ASGI server compatibility. In Django 2.0, all views are expected to be synchronous (def instead of async def), and trying to use an async view will throw errors because the WSGI-based server stack (which Django 2.0 relies on) can't handle async code directly.
How to Call Async APIs in a Synchronous Django 2.0 View
Since you can't use async views, you'll need to run your asynchronous API calls within a synchronous view using Python's asyncio module. Here's how to do it properly, including how to use get_event_loop():
Step 1: Define Your Async API Fetch Functions
First, write the async functions to fetch your API data using aiohttp:
import aiohttp import asyncio async def fetch_single_api(session, api_url): """Fetch data from a single API endpoint""" async with session.get(api_url) as response: # Handle HTTP errors if needed (e.g., response.raise_for_status()) return await response.json() async def fetch_multiple_apis(api_urls): """Fetch data from multiple APIs in parallel""" async with aiohttp.ClientSession() as session: # Create a list of async tasks for each API call tasks = [fetch_single_api(session, url) for url in api_urls] # Run all tasks in parallel and wait for all results # Order of results matches the order of your urls list, but calls are parallel results = await asyncio.gather(*tasks) return results
Step 2: Call Async Code from Your Synchronous View
In your Django view, you'll use asyncio.get_event_loop() to get the default event loop for the current thread, then run your async tasks until completion with run_until_complete():
from django.http import HttpResponse from myapp.models import MyDataModel def my_sync_view(request): # List of APIs to call (order doesn't matter for execution) target_apis = [ "https://api.example.com/resource1", "https://api.example.com/resource2", "https://api.example.com/resource3" ] # Get the event loop for the current thread loop = asyncio.get_event_loop() # Run the async task and wait for results api_results = loop.run_until_complete(fetch_multiple_apis(target_apis)) # Process results (e.g., save to database) for result in api_results: MyDataModel.objects.create( field1=result.get("key1"), field2=result.get("key2") ) return HttpResponse("API data fetched and saved successfully!")
About get_event_loop()
In a synchronous context (like your Django 2.0 view), asyncio.get_event_loop() retrieves the default event loop associated with the current thread. If no loop exists, it will create one automatically. This is the standard way to bridge synchronous code with async tasks in Python 3.6+.
A quick note: If you're running Django in a multi-threaded environment (most production WSGI servers are), each thread will have its own event loop, so you don't have to worry about cross-thread loop conflicts here.
Key Caveats to Keep in Mind
- Blocking the request thread: Even though your API calls are parallel, the synchronous view will block until all API calls finish. If your APIs are slow, this could lead to long request times or timeouts. For longer-running tasks, consider using a task queue like Celery to offload work to background workers instead.
aiohttpbest practices: Always useasync withforClientSessionto ensure connections are properly closed. Avoid reusing sessions across multiple requests unless you're using a session pool.- Python version compatibility: Python 3.6+ supports
async/await, so your code will work as written, but keep in mind that newer Python versions have improved asyncio features.
内容的提问来源于stack exchange,提问作者Gatothgaj

