{"title":"非同期サポート","version":"4.0","locale":"ja","docname":"topics/async","url":"/ja/4.0/topics/async/","canonical":"https://djangodocs.dev/ja/4.0/topics/async/","summary":"Djangoは、 ASGI の環境下であれば、完璧な非同期リクエストスタックに対応した非同期(\"async\")ビューをサポートしています。WSGIの環境下でも非同期ビューは動作しますが、パフォーマンス上不利であるうえ、長期的なリクエストを効率的に処理できません。…","html":"<h1>非同期サポート<a class=\"heading-anchor\" href=\"#asynchronous-support\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Djangoは、 <a class=\"reference internal\" href=\"/ja/4.0/howto/deployment/asgi/\"><span class=\"doc\">ASGI</span></a> の環境下であれば、完璧な非同期リクエストスタックに対応した非同期(&quot;async&quot;)ビューをサポートしています。WSGIの環境下でも非同期ビューは動作しますが、パフォーマンス上不利であるうえ、長期的なリクエストを効率的に処理できません。</p>\n<p>開発チームはORMや他の機能でも非同期処理が対応できるよう取り組んでいます。この機能は将来リリース予定ですが、現時点では、同期処理と非同期処理のやり取りに、 <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> アダプターが使えます。さらに同期処理と非同期処理を統合するために、非同期なPythonライブラリがすべて使えます。</p>\n<section id=\"async-views\">\n<h2>非同期ビュー<a class=\"heading-anchor\" href=\"#async-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>どのようなビューであれ、呼び出し可能オブジェクトでコルーチンを返すようにすれば、非同期にできます。その際には、一般的に``async def``を使います。関数ベースのビューの場合、<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">``</span></a>async def``を用いてビュー全体を宣言します。クラスベースのビューの場合、 <a href=\"#id3\"><span class=\"problematic\" id=\"id4\">``</span></a>__call__()``メソッドを``async def``で宣言します（<a href=\"#id5\"><span class=\"problematic\" id=\"id6\">``</span></a>__init__()``でも``as_view()``でもないことに注意）。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>Djangoは``asyncio.iscoroutinefunction``を使って、ビューが非同期かどうかテストします。コルーチンを返す独自のメソッドを実装する場合、ビューの``_is_coroutine``属性を``asyncio.coroutines._is_coroutine``に設定し、この関数が``True``を返すようにしてください。</p>\n</aside>\n<p>WSGIサーバーでは、非同期ビューは1回限りのイベントループで実行されます。つまり、非同期HTTPリクエストなどの非同期機能を問題なく使用できるものの、非同期スタックのメリットは得られないことになります。</p>\n<p>非同期スタックの主な利点とは、数百もの接続をPythonのスレッドを使わずに処理できることです。これにより、低速ストリーミング、ロングポーリング、その他の便利なレスポンスタイプが使えます。</p>\n<p>もしこれらを利用したい場合は、代わりに <a class=\"reference internal\" href=\"/ja/4.0/howto/deployment/asgi/\"><span class=\"doc\">ASGI</span></a> を使ってDjangoをデプロイする必要があります。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>同期ミドルウェアを使っていない場合にのみ、完全非同期のリクエストスタックの効果があります。もし、同期ミドルウェアがあれば、同期環境を安全にエミュレートするために、Djangoはリクエストごとにスレッドを使ってしまいます。</p>\n<p>ミドルウェアは、 <a class=\"reference internal\" href=\"/ja/4.0/topics/http/middleware/#async-middleware\"><span class=\"std std-ref\">both sync and async</span></a> コンテキストをサポートするように構築できます。 Djangoミドルウェアの一部はこのように構築されていますが、すべてではありません。ミドルウェアが適応する必要があるものを確認するには、 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.request</span></code> ロガーのデバッグロギングを有効にして、 <em>&quot;Synchronous middleware ... adapted&quot;</em> に関するログメッセージを探します。</p>\n</aside>\n<p>ASGIとWSGIの両方のモードで、非同期サポートを使用し、シリアルではなく並行してコードを実行することができます。これは特に、外部APIやデータストアを扱う場合に便利です。</p>\n<p>ORMのような、まだ同期的なDjangoの機能を呼び出したい場合、次のように:func:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>sync_to_async`でラップする必要があります。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n\n<span class=\"n\">results</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">Blog</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"mi\">123</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>次のコードのように、ORMのコードを独自の関数に移動して、その関数全体を:func:<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>sync_to_async`で呼び出す方が簡単だと思うかもしれません。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">_get_blog</span><span class=\"p\">(</span><span class=\"n\">pk</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"n\">Blog</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">select_related</span><span class=\"p\">(</span><span class=\"s1\">&#39;author&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"n\">pk</span><span class=\"p\">)</span>\n\n<span class=\"n\">get_blog</span> <span class=\"o\">=</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">_get_blog</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>非同期ビューから、同期的なDjangoの機能を誤って呼び出そうとすると、Djangoの&lt;async-safety&gt;が発動して、データが破損しないように保護されます。</p>\n<section id=\"performance\">\n<h3>パフォーマンス<a class=\"heading-anchor\" href=\"#performance\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When running in a mode that does not match the view (e.g. an async view under\nWSGI, or a traditional sync view under ASGI), Django must emulate the other\ncall style to allow your code to run. This context-switch causes a small\nperformance penalty of around a millisecond.</p>\n<p>This is also true of middleware. Django will attempt to minimize the number of\ncontext-switches between sync and async. If you have an ASGI server, but all\nyour middleware and views are synchronous, it will switch just once, before it\nenters the middleware stack.</p>\n<p>However, if you put synchronous middleware between an ASGI server and an\nasynchronous view, it will have to switch into sync mode for the middleware and\nthen back to async mode for the view. Django will also hold the sync thread\nopen for middleware exception propagation. This may not be noticeable at first,\nbut adding this penalty of one thread per request can remove any async\nperformance advantage.</p>\n<p>You should do your own performance testing to see what effect ASGI versus WSGI\nhas on your code. In some cases, there may be a performance increase even for\na purely synchronous codebase under ASGI because the request-handling code is\nstill all running asynchronously. In general you will only want to enable ASGI\nmode if you have asynchronous code in your project.</p>\n</section>\n</section>\n<section id=\"async-safety\">\n<span id=\"id1\"></span><h2>非同期安全性<a class=\"heading-anchor\" href=\"#async-safety\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"std envvar\">\n<dt class=\"sig sig-object std\" id=\"envvar-DJANGO_ALLOW_ASYNC_UNSAFE\">\n<span class=\"sig-name descname\"><span class=\"pre\">DJANGO_ALLOW_ASYNC_UNSAFE</span></span><a class=\"heading-anchor\" href=\"#envvar-DJANGO_ALLOW_ASYNC_UNSAFE\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Certain key parts of Django are not able to operate safely in an async\nenvironment, as they have global state that is not coroutine-aware. These parts\nof Django are classified as &quot;async-unsafe&quot;, and are protected from execution in\nan async environment. The ORM is the main example, but there are other parts\nthat are also protected in this way.</p>\n<p>If you try to run any of these parts from a thread where there is a <em>running\nevent loop</em>, you will get a\n<a class=\"reference internal\" href=\"/ja/4.0/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation\" title=\"django.core.exceptions.SynchronousOnlyOperation\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">SynchronousOnlyOperation</span></code></a> error. Note that you\ndon't have to be inside an async function directly to have this error occur. If\nyou have called a sync function directly from an async function,\nwithout using <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> or similar, then it can also occur. This is\nbecause your code is still running in a thread with an active event loop, even\nthough it may not be declared as async code.</p>\n<p>If you encounter this error, you should fix your code to not call the offending\ncode from an async context. Instead, write your code that talks to async-unsafe\nfunctions in its own, sync function, and call that using\n<a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">asgiref.sync.sync_to_async()</span></code></a> (or any other way of running sync code in\nits own thread).</p>\n<p>The async context can be imposed upon you by the environment in which you are\nrunning your Django code. For example, <a class=\"reference external\" href=\"https://jupyter.org/\">Jupyter</a> notebooks and <a class=\"reference external\" href=\"https://ipython.org\">IPython</a>\ninteractive shells both transparently provide an active event loop so that it is\neasier to interact with asynchronous APIs.</p>\n<p>If you're using an IPython shell, you can disable this event loop by running:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"o\">%</span><span class=\"n\">autoawait</span> <span class=\"n\">off</span>\n</code></pre></div>\n<p>as a command at the IPython prompt. This will allow you to run synchronous code\nwithout generating <a class=\"reference internal\" href=\"/ja/4.0/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation\" title=\"django.core.exceptions.SynchronousOnlyOperation\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">SynchronousOnlyOperation</span></code></a>\nerrors; however, you also won't be able to <code class=\"docutils literal notranslate\"><span class=\"pre\">await</span></code> asynchronous APIs. To turn\nthe event loop back on, run:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"o\">%</span><span class=\"n\">autoawait</span> <span class=\"n\">on</span>\n</code></pre></div>\n<p>If you're in an environment other than IPython (or you can't turn off\n<code class=\"docutils literal notranslate\"><span class=\"pre\">autoawait</span></code> in IPython for some reason), you are <em>certain</em> there is no chance\nof your code being run concurrently, and you <em>absolutely</em> need to run your sync\ncode from an async context, then you can disable the warning by setting the\n<span class=\"target\" id=\"index-0\"></span><a class=\"reference internal\" href=\"#envvar-DJANGO_ALLOW_ASYNC_UNSAFE\"><code class=\"xref std std-envvar docutils literal notranslate\"><span class=\"pre\">DJANGO_ALLOW_ASYNC_UNSAFE</span></code></a> environment variable to any value.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>このオプションを有効にした上で、Djangoの  async-unsafe パーツへ同時アクセスがあると、データが失われたり壊れたりする可能性があります。十分な注意を払い、本番環境では使用しないでください。</p>\n</aside>\n<p>もし、これをPython内部から行いたい場合は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">os.environ</span></code>:: を使用してください。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">os</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"p\">[</span><span class=\"s2\">&quot;DJANGO_ALLOW_ASYNC_UNSAFE&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;true&quot;</span>\n</code></pre></div>\n</section>\n<section id=\"async-adapter-functions\">\n<h2>Async adapter functions<a class=\"heading-anchor\" href=\"#async-adapter-functions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>It is necessary to adapt the calling style when calling sync code from an async\ncontext, or vice-versa. For this there are two adapter functions, from the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">asgiref.sync</span></code> module: <a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> and <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a>. They\nare used to transition between the calling styles while preserving\ncompatibility.</p>\n<p>These adapter functions are widely used in Django. The <a class=\"reference external\" href=\"https://pypi.org/project/asgiref/\">asgiref</a> package\nitself is part of the Django project, and it is automatically installed as a\ndependency when you install Django with <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code>.</p>\n<section id=\"async-to-sync\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code><a class=\"heading-anchor\" href=\"#async-to-sync\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"asgiref.sync.async_to_sync\">\n<span class=\"sig-name descname\"><span class=\"pre\">async_to_sync</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">async_function</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">force_new_loop</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#asgiref.sync.async_to_sync\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Takes an async function and returns a sync function that wraps it. Can be used\nas either a direct wrapper or a decorator:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">async_to_sync</span>\n\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_data</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n<span class=\"n\">sync_get_data</span> <span class=\"o\">=</span> <span class=\"n\">async_to_sync</span><span class=\"p\">(</span><span class=\"n\">get_data</span><span class=\"p\">)</span>\n\n<span class=\"nd\">@async_to_sync</span>\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_other_data</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>The async function is run in the event loop for the current thread, if one is\npresent. If there is no current event loop, a new event loop is spun up\nspecifically for the single async invocation and shut down again once it\ncompletes. In either situation, the async function will execute on a different\nthread to the calling code.</p>\n<p>Threadlocals and contextvars values are preserved across the boundary in both\ndirections.</p>\n<p><a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> is essentially a more powerful version of the\n<a class=\"reference external\" href=\"https://docs.python.org/3/library/asyncio-runner.html#asyncio.run\" title=\"(in Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">asyncio.run()</span></code></a> function in Python's standard library. As well\nas ensuring threadlocals work, it also enables the <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> mode of\n<a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> when that wrapper is used below it.</p>\n</section>\n<section id=\"sync-to-async\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code><a class=\"heading-anchor\" href=\"#sync-to-async\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"asgiref.sync.sync_to_async\">\n<span class=\"sig-name descname\"><span class=\"pre\">sync_to_async</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sync_function</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">thread_sensitive</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#asgiref.sync.sync_to_async\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Takes a sync function and returns an async function that wraps it. Can be used\nas either a direct wrapper or a decorator:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n\n<span class=\"n\">async_function</span> <span class=\"o\">=</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">sync_function</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"n\">async_function</span> <span class=\"o\">=</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">sensitive_sync_function</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n<span class=\"nd\">@sync_to_async</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">sync_function</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Threadlocals and contextvars values are preserved across the boundary in both\ndirections.</p>\n<p>Sync functions tend to be written assuming they all run in the main\nthread, so <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> has two threading modes:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive=True</span></code> (the default): the sync function will run in the\nsame thread as all other <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> functions. This will be the\nmain thread, if the main thread is synchronous and you are using the\n<a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> wrapper.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive=False</span></code>: the sync function will run in a brand new thread\nwhich is then closed once the invocation completes.</p></li>\n</ul>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">asgiref</span></code> version 3.3.0 changed the default value of the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> parameter to <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>. This is a safer default, and in\nmany cases interacting with Django the correct value, but be sure to\nevaluate uses of <code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code> if updating <code class=\"docutils literal notranslate\"><span class=\"pre\">asgiref</span></code> from a prior\nversion.</p>\n</aside>\n<p>Thread-sensitive mode is quite special, and does a lot of work to run all\nfunctions in the same thread. Note, though, that it <em>relies on usage of</em>\n<a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> <em>above it in the stack</em> to correctly run things on the\nmain thread. If you use <code class=\"docutils literal notranslate\"><span class=\"pre\">asyncio.run()</span></code> or similar, it will fall back to\nrunning thread-sensitive functions in a single, shared thread, but this will\nnot be the main thread.</p>\n<p>The reason this is needed in Django is that many libraries, specifically\ndatabase adapters, require that they are accessed in the same thread that they\nwere created in. Also a lot of existing Django code assumes it all runs in the\nsame thread, e.g. middleware adding things to a request for later use in views.</p>\n<p>Rather than introduce potential compatibility issues with this code, we instead\nopted to add this mode so that all existing Django sync code runs in the same\nthread and thus is fully compatible with async mode. Note that sync code will\nalways be in a <em>different</em> thread to any async code that is calling it, so you\nshould avoid passing raw database handles or other thread-sensitive references\naround.</p>\n<p>In practice this restriction means that you should not pass features of the\ndatabase <code class=\"docutils literal notranslate\"><span class=\"pre\">connection</span></code> object when calling <code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code>. Doing so will\ntrigger the thread safety checks:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"go\"># DJANGO_SETTINGS_MODULE=settings.py python -m asyncio</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">asyncio</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">connection</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># In an async context so you cannot use the database directly:</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">cursor</span><span class=\"p\">()</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">django.core.exceptions.SynchronousOnlyOperation: You cannot call this from</span>\n<span class=\"go\">an async context - use a thread or sync_to_async.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Nor can you pass resolved connection attributes across threads:</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">await</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">cursor</span><span class=\"p\">)()</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">django.db.utils.DatabaseError: DatabaseWrapper objects created in a thread</span>\n<span class=\"go\">can only be used in that same thread. The object with alias &#39;default&#39; was</span>\n<span class=\"go\">created in thread id 4371465600 and this is thread id 6131478528.</span>\n</code></pre></div>\n<p>Rather, you should encapsulate all database access within a helper function\nthat can be called with <code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code> without relying on the connection\nobject in the calling code.</p>\n</section>\n</section>","rootId":"asynchronous-support","toc":[{"title":"非同期ビュー","anchor":"async-views","children":[{"title":"パフォーマンス","anchor":"performance","children":[]}]},{"title":"非同期安全性","anchor":"async-safety","children":[]},{"title":"Async adapter functions","anchor":"async-adapter-functions","children":[{"title":"async_to_sync()","anchor":"async-to-sync","children":[]},{"title":"sync_to_async()","anchor":"sync-to-async","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/4.0/topics/"}],"prev":{"docname":"topics/external-packages","title":"External packages","url":"/ja/4.0/topics/external-packages/"},"next":{"docname":"howto/index","title":"「How-to」ガイド","url":"/ja/4.0/howto/"},"formats":{"html":"/ja/4.0/topics/async/","markdown":"/ja/4.0/topics/async.md","json":"/ja/4.0/topics/async.json"},"source":"https://github.com/django/django/blob/stable/4.0.x/docs/topics/async.txt","official":"https://docs.djangoproject.com/ja/4.0/topics/async/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}