Talking with a db, or doing http requests are IO operations, so instead of blocking the process, django can now start processing another one. When the IO operation is done, it continues where it stopped.
I don't know much about Python, but in a typical PHP/Apache setup, Apache simply starts as many processes as needed to answer all requests.
In python world you have few Django processes spawned by WSGI/ASGI app container, and those processes spawn python threads to handle requests. Because python uses GIL, no more than single thread is executed at single time per process. At specific times GIL stops running bytecode for one thread and moves to next one (eg when you do IO). This means other threads keep running, but in theory you can run out of threads.
In async you use tasks instead of threads for http requests, so single process can handle multiple requests at same time, only spawning threads at limited number of situations.
If your workload is IO bound (and most of web development is) async improves performance in any case.
In pseudo code I would think it would look like this:
def my_view(request):
name = async_get_name() // returns a promise
city = async_get_city() // returns a promise
waitUntilResolved(name,city)
return HttpResponse('Hello '+name+' from '+city)If a function like this exists, it would just sleep until the given promises are resolved. I don't see how that is realted to the term "multiprocess".