---
title: "非同期サポート"
version: 3.2
locale: ja
source: https://docs.djangoproject.com/ja/3.2/topics/async/
canonical: https://djangodocs.dev/ja/3.2/topics/async/
---
# 非同期サポート

Djangoは、 [ASGI](/ja/3.2/howto/deployment/asgi/) の環境下であれば、完璧な非同期リクエストスタックに対応した非同期("async")ビューをサポートしています。WSGIの環境下でも非同期ビューは動作しますが、パフォーマンス上不利であるうえ、長期的なリクエストを効率的に処理できません。

開発チームはORMや他の機能でも非同期処理が対応できるよう取り組んでいます。この機能は将来リリース予定ですが、現時点では、同期処理と非同期処理のやり取りに、 [`sync_to_async()`](#asgiref.sync.sync_to_async) アダプターが使えます。さらに同期処理と非同期処理を統合するために、非同期なPythonライブラリがすべて使えます。

> **Changed in Django 3.1**
>
> 非同期ビューへのサポートが追加されました。

## 非同期ビュー

> **New in Django 3.1**

Any view can be declared async by making the callable part of it return a
coroutine - commonly, this is done using `async def`. For a function-based
view, this means declaring the whole view using `async def`. For a
class-based view, this means making its `__call__()` method an `async def`
(not its `__init__()` or `as_view()`).

> **Note**
>
> Django uses `asyncio.iscoroutinefunction` to test if your view is
> asynchronous or not. If you implement your own method of returning a
> coroutine, ensure you set the `_is_coroutine` attribute of the view
> to `asyncio.coroutines._is_coroutine` so this function returns `True`.

WSGIサーバーでは、非同期ビューは1回限りのイベントループで実行されます。つまり、非同期HTTPリクエストなどの非同期機能を問題なく使用できるものの、非同期スタックのメリットは得られないことになります。

非同期スタックの主な利点とは、数百もの接続をPythonのスレッドを使わずに処理できることです。これにより、低速ストリーミング、ロングポーリング、その他の便利なレスポンスタイプが使えます。

もしこれらを利用したい場合は、代わりに [ASGI](/ja/3.2/howto/deployment/asgi/) を使ってDjangoをデプロイする必要があります。

> **Warning**
>
> 同期ミドルウェアを使っていない場合にのみ、完全非同期のリクエストスタックの効果があります。もし、同期ミドルウェアがあれば、同期環境を安全にエミュレートするために、Djangoはリクエストごとにスレッドを使ってしまいます。
>
> ミドルウェアは、 [both sync and async](/ja/3.2/topics/http/middleware/#async-middleware) コンテキストをサポートするように構築できます。 Djangoミドルウェアの一部はこのように構築されていますが、すべてではありません。ミドルウェアが適応する必要があるものを確認するには、 `django.request` ロガーのデバッグロギングを有効にして、 *"Synchronous middleware ... adapted"* に関するログメッセージを探します。

ASGIとWSGIの両方のモードで、非同期サポートを使用し、シリアルではなく並行してコードを実行することができます。これは特に、外部APIやデータストアを扱う場合に便利です。

If you want to call a part of Django that is still synchronous, like the ORM,
you will need to wrap it in a [`sync_to_async()`](#asgiref.sync.sync_to_async) call. For example:

```
from asgiref.sync import sync_to_async

results = await sync_to_async(Blog.objects.get, thread_sensitive=True)(pk=123)
```

You may find it easier to move any ORM code into its own function and call that
entire function using [`sync_to_async()`](#asgiref.sync.sync_to_async). For example:

```
from asgiref.sync import sync_to_async

def _get_blog(pk):
    return Blog.objects.select_related('author').get(pk=pk)

get_blog = sync_to_async(_get_blog, thread_sensitive=True)
```

If you accidentally try to call a part of Django that is still synchronous-only
from an async view, you will trigger Django's
[asynchronous safety protection](#async-safety) to protect your data from
corruption.

### Performance

When running in a mode that does not match the view (e.g. an async view under
WSGI, or a traditional sync view under ASGI), Django must emulate the other
call style to allow your code to run. This context-switch causes a small
performance penalty of around a millisecond.

This is also true of middleware. Django will attempt to minimize the number of
context-switches between sync and async. If you have an ASGI server, but all
your middleware and views are synchronous, it will switch just once, before it
enters the middleware stack.

However, if you put synchronous middleware between an ASGI server and an
asynchronous view, it will have to switch into sync mode for the middleware and
then back to async mode for the view. Django will also hold the sync thread
open for middleware exception propagation. This may not be noticeable at first,
but adding this penalty of one thread per request can remove any async
performance advantage.

You should do your own performance testing to see what effect ASGI versus WSGI
has on your code. In some cases, there may be a performance increase even for
a purely synchronous codebase under ASGI because the request-handling code is
still all running asynchronously. In general you will only want to enable ASGI
mode if you have asynchronous code in your project.

## Async safety

#### `DJANGO_ALLOW_ASYNC_UNSAFE`

Certain key parts of Django are not able to operate safely in an async
environment, as they have global state that is not coroutine-aware. These parts
of Django are classified as "async-unsafe", and are protected from execution in
an async environment. The ORM is the main example, but there are other parts
that are also protected in this way.

If you try to run any of these parts from a thread where there is a *running
event loop*, you will get a
[`SynchronousOnlyOperation`](/ja/3.2/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation) error. Note that you
don't have to be inside an async function directly to have this error occur. If
you have called a sync function directly from an async function,
without using [`sync_to_async()`](#asgiref.sync.sync_to_async) or similar, then it can also occur. This is
because your code is still running in a thread with an active event loop, even
though it may not be declared as async code.

If you encounter this error, you should fix your code to not call the offending
code from an async context. Instead, write your code that talks to async-unsafe
functions in its own, sync function, and call that using
[`asgiref.sync.sync_to_async()`](#asgiref.sync.sync_to_async) (or any other way of running sync code in
its own thread).

The async context can be imposed upon you by the environment in which you are
running your Django code. For example, [Jupyter](https://jupyter.org/) notebooks and [IPython](https://ipython.org)
interactive shells both transparently provide an active event loop so that it is
easier to interact with asynchronous APIs.

If you're using an IPython shell, you can disable this event loop by running:

```
%autoawait off
```

as a command at the IPython prompt. This will allow you to run synchronous code
without generating [`SynchronousOnlyOperation`](/ja/3.2/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation)
errors; however, you also won't be able to `await` asynchronous APIs. To turn
the event loop back on, run:

```
%autoawait on
```

If you're in an environment other than IPython (or you can't turn off
`autoawait` in IPython for some reason), you are *certain* there is no chance
of your code being run concurrently, and you *absolutely* need to run your sync
code from an async context, then you can disable the warning by setting the
[`DJANGO_ALLOW_ASYNC_UNSAFE`](#envvar-DJANGO_ALLOW_ASYNC_UNSAFE) environment variable to any value.

> **Warning**
>
> このオプションを有効にした上で、Djangoの  async-unsafe パーツへ同時アクセスがあると、データが失われたり壊れたりする可能性があります。十分な注意を払い、本番環境では使用しないでください。

もし、これをPython内部から行いたい場合は、 `os.environ`:: を使用してください。

```
import os

os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
```

## Async adapter functions

It is necessary to adapt the calling style when calling sync code from an async
context, or vice-versa. For this there are two adapter functions, from the
`asgiref.sync` module: [`async_to_sync()`](#asgiref.sync.async_to_sync) and [`sync_to_async()`](#asgiref.sync.sync_to_async). They
are used to transition between the calling styles while preserving
compatibility.

These adapter functions are widely used in Django. The [asgiref](https://pypi.org/project/asgiref/) package
itself is part of the Django project, and it is automatically installed as a
dependency when you install Django with `pip`.

### `async_to_sync()`

#### `async_to_sync(async_function, force_new_loop=False)`

Takes an async function and returns a sync function that wraps it. Can be used
as either a direct wrapper or a decorator:

```
from asgiref.sync import async_to_sync

async def get_data(...):
    ...

sync_get_data = async_to_sync(get_data)

@async_to_sync
async def get_other_data(...):
    ...
```

The async function is run in the event loop for the current thread, if one is
present. If there is no current event loop, a new event loop is spun up
specifically for the single async invocation and shut down again once it
completes. In either situation, the async function will execute on a different
thread to the calling code.

Threadlocals and contextvars values are preserved across the boundary in both
directions.

[`async_to_sync()`](#asgiref.sync.async_to_sync) is essentially a more powerful version of the
[`asyncio.run()`](https://docs.python.org/3/library/asyncio-runner.html#asyncio.run) function in Python's standard library. As well
as ensuring threadlocals work, it also enables the `thread_sensitive` mode of
[`sync_to_async()`](#asgiref.sync.sync_to_async) when that wrapper is used below it.

### `sync_to_async()`

#### `sync_to_async(sync_function, thread_sensitive=True)`

Takes a sync function and returns an async function that wraps it. Can be used
as either a direct wrapper or a decorator:

```
from asgiref.sync import sync_to_async

async_function = sync_to_async(sync_function, thread_sensitive=False)
async_function = sync_to_async(sensitive_sync_function, thread_sensitive=True)

@sync_to_async
def sync_function(...):
    ...
```

Threadlocals and contextvars values are preserved across the boundary in both
directions.

Sync functions tend to be written assuming they all run in the main
thread, so [`sync_to_async()`](#asgiref.sync.sync_to_async) has two threading modes:

- `thread_sensitive=True` (the default): the sync function will run in the
  same thread as all other `thread_sensitive` functions. This will be the
  main thread, if the main thread is synchronous and you are using the
  [`async_to_sync()`](#asgiref.sync.async_to_sync) wrapper.
- `thread_sensitive=False`: the sync function will run in a brand new thread
  which is then closed once the invocation completes.

> **Warning**
>
> `asgiref` version 3.3.0 changed the default value of the
> `thread_sensitive` parameter to `True`. This is a safer default, and in
> many cases interacting with Django the correct value, but be sure to
> evaluate uses of `sync_to_async()` if updating `asgiref` from a prior
> version.

Thread-sensitive mode is quite special, and does a lot of work to run all
functions in the same thread. Note, though, that it *relies on usage of*
[`async_to_sync()`](#asgiref.sync.async_to_sync) *above it in the stack* to correctly run things on the
main thread. If you use `asyncio.run()` or similar, it will fall back to
running thread-sensitive functions in a single, shared thread, but this will
not be the main thread.

The reason this is needed in Django is that many libraries, specifically
database adapters, require that they are accessed in the same thread that they
were created in. Also a lot of existing Django code assumes it all runs in the
same thread, e.g. middleware adding things to a request for later use in views.

Rather than introduce potential compatibility issues with this code, we instead
opted to add this mode so that all existing Django sync code runs in the same
thread and thus is fully compatible with async mode. Note that sync code will
always be in a *different* thread to any async code that is calling it, so you
should avoid passing raw database handles or other thread-sensitive references
around.
