{"title":"Gestion du code asynchrone","version":"6.1","locale":"fr","docname":"topics/async","url":"/fr/6.1/topics/async/","canonical":"https://djangodocs.dev/fr/6.1/topics/async/","summary":"Django prend en charge l’écriture de vues asynchrones (« async »), en conjonction avec une pile de requête adaptée pour l’asynchrone, pour autant que vous…","html":"<h1>Gestion du code asynchrone<a class=\"heading-anchor\" href=\"#asynchronous-support\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django prend en charge l’écriture de vues asynchrones (« async »), en conjonction avec une pile de requête adaptée pour l’asynchrone, pour autant que vous fonctionniez avec <a class=\"reference internal\" href=\"/fr/6.1/howto/deployment/asgi/\"><span class=\"doc\">ASGI</span></a>. Les vues asynchrones fonctionnent aussi avec WSGI, mais avec un léger coût d’adaptation pour chaque requête (voir <a class=\"reference internal\" href=\"#async-performance\"><span class=\"std std-ref\">Performance</span></a>) et sans possibilité de bénéficier de requêtes de longue durée efficaces.</p>\n<p>De nombreuses parties de Django fournissent des API asynchrones, dont <a class=\"reference internal\" href=\"/fr/6.1/topics/db/queries/#async-queries\"><span class=\"std std-ref\">l’ORM</span></a>, l’infrastructure de cache, l’authentification, les sessions et les signaux. Pour le reste du code, l’adaptateur <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\">sync_to_async()</code></a> est une passerelle à faible coût (voir <a class=\"reference internal\" href=\"#async-performance\"><span class=\"std std-ref\">Performance</span></a>). Une large gamme de bibliothèques Python nativement asynchrones peuvent aussi être intégrées.</p>\n<section id=\"async-views\">\n<h2>Vues asynchrones<a class=\"heading-anchor\" href=\"#async-views\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Toute vue peut être déclarée asynchrone en faisant renvoyer une coroutine de sa partie exécutable ; ceci se fait en principe avec <code class=\"docutils literal notranslate\">async def</code>. Pour une vue basée sur une fonction, cela signifie déclarer la vue entière comme <code class=\"docutils literal notranslate\">async def</code>. Pour une vue basée sur une classe, cela signifie définir les gestionnaires de méthodes tels que  <code class=\"docutils literal notranslate\">get()</code> et <code class=\"docutils literal notranslate\">post()</code> comme <code class=\"docutils literal notranslate\">async def</code> (pas la méthode <code class=\"docutils literal notranslate\">__init__()</code> ni <code class=\"docutils literal notranslate\">as_view()</code>).</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Django utilise <code class=\"docutils literal notranslate\">inspect.iscoroutinefunction</code> pour tester si la vue est asynchrone ou pas. Si vous implémentez votre propre méthode pour renvoyer une coroutine, prenez soin d’utiliser <code class=\"docutils literal notranslate\">inspect.markcoroutinefunction</code> pour que cette fonction renvoie <code class=\"docutils literal notranslate\">True</code>.</p>\n</aside>\n<p>Avec un serveur WSGI, les vues asynchrones tournent dans leur propre boucle événementielle unique. Cela veut dire que vous pouvez utiliser sans problème des fonctionnalités asynchrones, telles que des requêtes HTTP asynchrones et concurrentes, mais vous ne bénéficierez pas des avantages d’une pile asynchrone.</p>\n<p>Les bénéfices principaux sont de pouvoir servir des centaines de connexions sans faire appel aux files d’exécutions (threads) Python. Cela vous permet d’utiliser les flux lents et les interrogations lentes (slow streaming, long-polling), et autres techniques semblables pour les réponses.</p>\n<p>Si vous souhaitez exploiter ces possibilités, vous devrez déployer Django en utilisant plutôt un serveur <a class=\"reference internal\" href=\"/fr/6.1/howto/deployment/asgi/\"><span class=\"doc\">ASGI</span></a>.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Une pile de requêtes entièrement asynchrone exige un intergiciel asynchrone de bout en bout. Lorsqu’un élément d’intergiciel synchrone se situe entre un serveur ASGI et une vue asynchrone, Django l’adapte en l’exécutant dans son propre fil ; voir <a class=\"reference internal\" href=\"#async-performance\"><span class=\"std std-ref\">Performance</span></a> pour le compromis de performance.</p>\n<p>Les intergiciels livrés par Django prennent en charge aussi bien le <a class=\"reference internal\" href=\"/fr/6.1/topics/http/middleware/#async-middleware\"><span class=\"std std-ref\">synchrone que l’asynchrone</span></a>.  Les intergiciels tiers ne le font pas forcément. Pour voir quels sont les intergiciels que Django adapte, activez la journalisation de débogage pour le journaliseur <code class=\"docutils literal notranslate\">django.request</code> et observer les messages mentionnant <em>« Asynchronous handler adapted for middleware… »</em>.</p>\n</aside>\n<p>Que ce soit en mode ASGI ou WSGI, vous pouvez toujours exploiter la prise en charge asynchrone de manière sûre pour exécuter du code de manière concurrente plutôt qu’en série. C’est particulièrement pratique lorsqu’on interagit avec des API externes ou des stockages de données.</p>\n<p>Si vous souhaitez appeler une partie de Django qui est encore synchrone, il vous faut l’envelopper dans un appel à <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\">sync_to_async()</code></a>. Par exemple</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=\"nn\">asgiref.sync</span> <span class=\"kn\">import</span> sync_to_async\n\nresults <span class=\"o\">=</span> <span class=\"k\">await</span> sync_to_async<span class=\"p\">(</span>sync_function<span class=\"p\">,</span> thread_sensitive<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span>pk<span class=\"o\">=</span><span class=\"mi\">123</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si par accident vous essayez d’appeler une partie de Django qui est purement synchrone à partir d’une vue asynchrone, vous déclencherez la <a class=\"reference internal\" href=\"#async-safety\"><span class=\"std std-ref\">protection de sécurité asynchrone</span></a> de Django qui vise à protéger vos données d’une éventuelle corruption.</p>\n<section id=\"decorators\">\n<h3>Décorateurs<a class=\"heading-anchor\" href=\"#decorators\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les décorateurs suivants peuvent être utilisés avec des fonctions de vues à la fois synchrones et asynchrones :</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.cache.cache_control\" title=\"django.views.decorators.cache.cache_control\"><code class=\"xref py py-func docutils literal notranslate\">cache_control()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.cache.never_cache\" title=\"django.views.decorators.cache.never_cache\"><code class=\"xref py py-func docutils literal notranslate\">never_cache()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.common.no_append_slash\" title=\"django.views.decorators.common.no_append_slash\"><code class=\"xref py py-func docutils literal notranslate\">no_append_slash()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/ref/csp/#django.views.decorators.csp.csp_override\" title=\"django.views.decorators.csp.csp_override\"><code class=\"xref py py-func docutils literal notranslate\">csp_override()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/ref/csp/#django.views.decorators.csp.csp_report_only_override\" title=\"django.views.decorators.csp.csp_report_only_override\"><code class=\"xref py py-func docutils literal notranslate\">csp_report_only_override()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/ref/csrf/#django.views.decorators.csrf.csrf_exempt\" title=\"django.views.decorators.csrf.csrf_exempt\"><code class=\"xref py py-func docutils literal notranslate\">csrf_exempt()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/ref/csrf/#django.views.decorators.csrf.csrf_protect\" title=\"django.views.decorators.csrf.csrf_protect\"><code class=\"xref py py-func docutils literal notranslate\">csrf_protect()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/ref/csrf/#django.views.decorators.csrf.ensure_csrf_cookie\" title=\"django.views.decorators.csrf.ensure_csrf_cookie\"><code class=\"xref py py-func docutils literal notranslate\">ensure_csrf_cookie()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/ref/csrf/#django.views.decorators.csrf.requires_csrf_token\" title=\"django.views.decorators.csrf.requires_csrf_token\"><code class=\"xref py py-func docutils literal notranslate\">requires_csrf_token()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/howto/error-reporting/#django.views.decorators.debug.sensitive_variables\" title=\"django.views.decorators.debug.sensitive_variables\"><code class=\"xref py py-func docutils literal notranslate\">sensitive_variables()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/howto/error-reporting/#django.views.decorators.debug.sensitive_post_parameters\" title=\"django.views.decorators.debug.sensitive_post_parameters\"><code class=\"xref py py-func docutils literal notranslate\">sensitive_post_parameters()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.gzip.gzip_page\" title=\"django.views.decorators.gzip.gzip_page\"><code class=\"xref py py-func docutils literal notranslate\">gzip_page()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.http.condition\" title=\"django.views.decorators.http.condition\"><code class=\"xref py py-func docutils literal notranslate\">condition()</code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\">conditional_page()</code></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.http.etag\" title=\"django.views.decorators.http.etag\"><code class=\"xref py py-func docutils literal notranslate\">etag()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.http.last_modified\" title=\"django.views.decorators.http.last_modified\"><code class=\"xref py py-func docutils literal notranslate\">last_modified()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.http.require_http_methods\" title=\"django.views.decorators.http.require_http_methods\"><code class=\"xref py py-func docutils literal notranslate\">require_http_methods()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.http.require_GET\" title=\"django.views.decorators.http.require_GET\"><code class=\"xref py py-func docutils literal notranslate\">require_GET()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.http.require_POST\" title=\"django.views.decorators.http.require_POST\"><code class=\"xref py py-func docutils literal notranslate\">require_POST()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.http.require_safe\" title=\"django.views.decorators.http.require_safe\"><code class=\"xref py py-func docutils literal notranslate\">require_safe()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.vary.vary_on_cookie\" title=\"django.views.decorators.vary.vary_on_cookie\"><code class=\"xref py py-func docutils literal notranslate\">vary_on_cookie()</code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/6.1/topics/http/decorators/#django.views.decorators.vary.vary_on_headers\" title=\"django.views.decorators.vary.vary_on_headers\"><code class=\"xref py py-func docutils literal notranslate\">vary_on_headers()</code></a></p></li>\n<li><p><code class=\"docutils literal notranslate\">xframe_options_deny()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">xframe_options_sameorigin()</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">xframe_options_exempt()</code></p></li>\n</ul>\n<p>Par exemple :</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=\"nn\">django.views.decorators.cache</span> <span class=\"kn\">import</span> never_cache\n\n\n<span class=\"nd\">@never_cache</span>\n<span class=\"k\">def</span> <span class=\"nf\">my_sync_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n\n<span class=\"nd\">@never_cache</span>\n<span class=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">my_async_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p><a class=\"reference internal\" href=\"/fr/6.1/ref/utils/#django.utils.decorators.method_decorator\" title=\"django.utils.decorators.method_decorator\"><code class=\"xref py py-func docutils literal notranslate\">method_decorator()</code></a> peut être utilisé avec des méthodes asynchrones, y compris avec des gestionnaires de vues <code class=\"docutils literal notranslate\">async def</code>. Notez cependant que si vous décorez <a class=\"reference internal\" href=\"/fr/6.1/ref/class-based-views/base/#django.views.generic.base.View.dispatch\" title=\"django.views.generic.base.View.dispatch\"><code class=\"xref py py-meth docutils literal notranslate\">dispatch()</code></a> sur une <code class=\"docutils literal notranslate\">View</code> avec des gestionnaires asynchrones, vous devrez surcharger <code class=\"docutils literal notranslate\">dispatch</code> pour la rendre aussi <code class=\"docutils literal notranslate\">async def</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=\"k\">class</span> <span class=\"nc\">MyClass</span><span class=\"p\">(</span>View<span class=\"p\">):</span>\n    <span class=\"nd\">@method_decorator</span><span class=\"p\">(</span>never_cache<span class=\"p\">)</span>\n    <span class=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">dispatch</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>dispatch<span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n\n    <span class=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">get</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> request<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">post</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> request<span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Ici, comme nous décorons <code class=\"docutils literal notranslate\">dispatch</code> plutôt que des méthodes de gestionnaire individuel, nous devons rendre <code class=\"docutils literal notranslate\">dispatch</code> asynchrone afin que <code class=\"docutils literal notranslate\">method_decorator</code> puisse marquer correctement la méthode résultante comme fonction coroutine.</p>\n</section>\n<section id=\"queries-the-orm\">\n<h3>Requêtes et ORM<a class=\"heading-anchor\" href=\"#queries-the-orm\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>À part quelques exceptions, Django peut lancer des requêtes d’ORM de manière asynchrone :</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=\"k\">async</span> <span class=\"k\">for</span> author <span class=\"ow\">in</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>name__startswith<span class=\"o\">=</span><span class=\"s2\">&quot;A&quot;</span><span class=\"p\">):</span>\n    book <span class=\"o\">=</span> <span class=\"k\">await</span> author<span class=\"o\">.</span>books<span class=\"o\">.</span>afirst<span class=\"p\">()</span>\n</code></pre></div>\n<p>Des notes détaillées peuvent être consultées dans <a class=\"reference internal\" href=\"/fr/6.1/topics/db/queries/#async-queries\"><span class=\"std std-ref\">Requêtes asynchrones</span></a>, mais en résumé :</p>\n<ul class=\"simple\">\n<li><p>Toutes les méthodes <code class=\"docutils literal notranslate\">QuerySet</code> générant une requête SQL possèdent une variante asynchrone dotée du préfixe <code class=\"docutils literal notranslate\">a</code>.</p></li>\n<li><p><code class=\"docutils literal notranslate\">async for</code> est pris en charge pour tous les QuerySets (y compris les résultats de <code class=\"docutils literal notranslate\">values()</code> et <code class=\"docutils literal notranslate\">values_list()</code>).</p></li>\n</ul>\n<p>Les méthodes de modèles asynchrones utilisant la base de données sont également prises en charge :</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=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">make_book</span><span class=\"p\">(</span><span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n    book <span class=\"o\">=</span> Book<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    <span class=\"k\">await</span> book<span class=\"o\">.</span>asave<span class=\"p\">(</span>using<span class=\"o\">=</span><span class=\"s2\">&quot;secondary&quot;</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">make_book_with_tags</span><span class=\"p\">(</span>tags<span class=\"p\">,</span> <span class=\"o\">*</span>args<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n    book <span class=\"o\">=</span> <span class=\"k\">await</span> Book<span class=\"o\">.</span>objects<span class=\"o\">.</span>acreate<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    <span class=\"k\">await</span> book<span class=\"o\">.</span>tags<span class=\"o\">.</span>aset<span class=\"p\">(</span>tags<span class=\"p\">)</span>\n</code></pre></div>\n<p>Les transactions ne fonctionnent pas encore en mode asynchrone. Si vous écrivez un bout de code nécessitant un comportement transactionnel, nous vous recommandons de l’écrire sous forme d’une seule fonction synchrone et de l’appeler avec <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\">sync_to_async()</code></a>.</p>\n<p>Les <a class=\"reference internal\" href=\"/fr/6.1/ref/databases/#persistent-database-connections\"><span class=\"std std-ref\">connexions persistantes à la base de données</span></a> définies par le réglage  <a class=\"reference internal\" href=\"/fr/6.1/ref/settings/#std-setting-CONN_MAX_AGE\"><code class=\"xref std std-setting docutils literal notranslate\">CONN_MAX_AGE</code></a>, devraient aussi être désactivées en mode asynchrone. À la place, nous suggérons d’utiliser le système de pool de connexions de votre moteur de base de données, si disponible, ou recherchez un système de tierce partie si nécessaire. Comme pour Django en mode synchrone, les requêtes concurrentes dans un même processus partagent ce pool, il s’agit donc de le dimensionner en fonction de la concurrence de requêtes ciblée en production.</p>\n</section>\n<section id=\"performance\">\n<span id=\"async-performance\"></span><h3>Performance<a class=\"heading-anchor\" href=\"#performance\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>En fonctionnement dans un mode ne correspondant pas à celui de la vue (par ex. une vue asynchrone sous WSGI ou une vue synchrone traditionnelle sous ASGI), Django doit émuler l’autre style d’appel pour permettre au code de fonctionner. Le coût par appel de cette adaptation est faible : quelques dizaines de microsecondes dans le chemin ASGI en requête, lorsque la boucle événementielle existante est réutilisée, et quelques centaines de microsecondes dans le chemin « à froid » utilisé par les commandes d’administration, les tâches d’arrière-plan et les scripts. En comparaison des temps de requête typiques mesurés en millisecondes, ces temps sont rarement perceptibles, mais peuvent le devenir sous contention GIL (interpréteur global) car le nombre de fils d’exécution actifs augmente.</p>\n<p>Si vous vous retrouvez à envelopper des lignes ou opérations dans une boucle serrée, restructurez votre code pour que la boucle fonctionne dans une seule opération <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\">sync_to_async()</code></a> (ou <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\">async_to_sync()</code></a>). Le coût par appel de la bascule de contexte est alors partagé par la boucle entière et disparaît pratiquement.</p>\n<p>Ce même coût d’adaptation par appel vaut aussi pour les intergiciels. Django essaie de minimiser le nombre de bascules de contexte entre code synchrone et asynchrone. Si vous fonctionnez avec un serveur ASGI mais que tous vos intergiciels et vues sont synchrones, la bascule ne se fait qu’une fois, avant d’entrer dans la pile des intergiciels.</p>\n<p>Cependant, si vous placez un intergiciel synchrone entre un serveur ASGI et une vue asynchrone, Django devra basculer en mode synchrone pour l’intergiciel puis revenir en mode asynchrone pour la vue. Il devra aussi laisser le fil d’exécution synchrone ouvert pour la propagation des exceptions d’intergiciel. Pour les vues requête/réponse qui sollicitent l’ORM, puis se terminent, la pénalité est en principe négligeable. Cela est par contre plus conséquent en mode ASGI pour des concurrences élevées dans un processus pour des entrées/sorties non liées à l’ORM (par exemple des multi-requêtes HTTP amont (fan-out), les événements envoyés par les serveurs (SSE) ou les requêtes longue durée), où le fil d’exécution supplémentaire par requête atteint les limites de concurrence.</p>\n<p>Nous suggérons de faire vos propres tests de performance pour observer les différences entre ASGI et WSGI avec votre code. Dans certains cas, les performances peuvent être meilleures avec ASGI même pour une base de code purement synchrone car le code de traitement des requêtes fonctionne toujours de manière asynchrone. Mais en général, l’activation du mode ASGI n’est profitable que si votre code contient du code asynchrone.</p>\n</section>\n<section id=\"handling-disconnects\">\n<span id=\"async-handling-disconnect\"></span><h3>Gestion des déconnexions<a class=\"heading-anchor\" href=\"#handling-disconnects\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Pour les requêtes de longue durée, un client peut se déconnecter avant que la vue renvoie une réponse. Dans ce cas, <code class=\"docutils literal notranslate\">asyncio.CancelledError</code> sera générée dans la vue. Vous pouvez intercepter cette erreur et la traiter si vous avez besoin d’effectuer un quelconque nettoyage :</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=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">my_view</span><span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"k\">try</span><span class=\"p\">:</span>\n        <span class=\"c1\"># Do some work</span>\n        <span class=\"o\">...</span>\n    <span class=\"k\">except</span> asyncio<span class=\"o\">.</span>CancelledError<span class=\"p\">:</span>\n        <span class=\"c1\"># Handle disconnect</span>\n        <span class=\"k\">raise</span>\n</code></pre></div>\n<p>Vous pouvez aussi <a class=\"reference internal\" href=\"/fr/6.1/ref/request-response/#request-response-streaming-disconnect\"><span class=\"std std-ref\">traiter les déconnexions de client dans les réponses en flux</span></a>.</p>\n</section>\n</section>\n<section id=\"async-safety\">\n<span id=\"id1\"></span><h2>Isolation de code asynchrone<a class=\"heading-anchor\" href=\"#async-safety\"><span class=\"visually-hidden\">Lien vers cette rubrique</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\">DJANGO_ALLOW_ASYNC_UNSAFE</span><a class=\"heading-anchor\" href=\"#envvar-DJANGO_ALLOW_ASYNC_UNSAFE\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Certaines parties essentielles de Django ne sont pas capables d’opération de manière sûre dans un environnement asynchrone, car elles se basent sur un état global qui n’est pas compatible avec les coroutines. Ces parties de Django sont classées comme non sûres pour l’asynchrone (« async-unsafe ») et sont protégées contre l’exécution dans un environnement asynchrone. L’API synchrone de l’ORM en est l’exemple principal, mais d’autres parties sont protégées de la même manière.</p>\n<p>Si vous essayez d’exécuter l’une de ces parties depuis un fil d’exécution où une <em>boucle événementielle s’exécute</em>, vous obtiendrez une erreur <a class=\"reference internal\" href=\"/fr/6.1/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation\" title=\"django.core.exceptions.SynchronousOnlyOperation\"><code class=\"xref py py-exc docutils literal notranslate\">SynchronousOnlyOperation</code></a>. Notez que vous n’avez pas besoin d’être directement dans une fonction asynchrone pour déclencher cette erreur. Si vous avez appelé une fonction synchrone directement depuis une fonction asynchrone sans utiliser <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\">sync_to_async()</code></a> ou un équivalent, cela peut alors aussi arriver, car votre code se trouve encore dans un fil d’exécution avec une boucle événementielle active, même s’il n’est pas déclaré comme code asynchrone.</p>\n<p>Si vous obtenez cette erreur, vous devriez corriger votre code pour qu’il n’appelle pas le code de manière fautive depuis un contexte asynchrone. Au lieu de cela, écrivez le code communiquant avec des fonctions non adaptées à l’asynchrone dans sa propre fonction synchrone et en l’appelant par <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\">asgiref.sync.sync_to_async()</code></a> (ou toute autre méthode d’exécution de code synchrone dans son propre fil d’exécution).</p>\n<p>Le contexte asynchrone peut vous être imposé par l’environnement dans lequel s’exécute le code Django. Par exemple, les carnets <a class=\"reference external\" href=\"https://jupyter.org/\">Jupyter</a> et les shells interactifs <a class=\"reference external\" href=\"https://ipython.org\">IPython</a> fournissent tous deux de manière transparente une boucle évènementielle active pour qu’il soit plus facile d’interagir avec des API asynchrones.</p>\n<p>Si vous utilisez un shell IPython, vous pouvez désactiver cette boucle évènementielle en exécutant :</p>\n<div class=\"code-block\" data-language=\"shell\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code>%autoawait off\n</code></pre></div>\n<p>comme commande à l’invite IPython. Cela permet d’exécuter du code synchrone sans que des erreurs <a class=\"reference internal\" href=\"/fr/6.1/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation\" title=\"django.core.exceptions.SynchronousOnlyOperation\"><code class=\"xref py py-exc docutils literal notranslate\">SynchronousOnlyOperation</code></a> se produisent ; cependant, vous ne serez pas non plus capable d’appeler des API asynchrones par <code class=\"docutils literal notranslate\">await</code>. Pour réactiver la boucle évènementielle, exécutez :</p>\n<div class=\"code-block\" data-language=\"shell\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</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=\"Shell code\"><code>%autoawait on\n</code></pre></div>\n<p>Si vous vous trouvez dans un environnement autre que IPython (ou que vous ne pouvez pas désactiver <code class=\"docutils literal notranslate\">autoawait</code> dans IPython pour une raison quelconque), que vous êtes <em>certain</em> qu’il n’y a aucun risque que le code soit lancé de manière concurrente et que vous avez <em>absolument</em> besoin de lancer ce code synchrone à partir d’un contexte asynchrone, vous pouvez alors désactiver l’avertissement en définissant la variable d’environnement <span class=\"target\" id=\"index-2\"></span><a class=\"reference internal\" href=\"#envvar-DJANGO_ALLOW_ASYNC_UNSAFE\"><code class=\"xref std std-envvar docutils literal notranslate\">DJANGO_ALLOW_ASYNC_UNSAFE</code></a> à une valeur quelconque.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Si vous activez cette option et qu’un accès concurrent se produit sur des parties de Django non adaptées à l’asynchrone, vous pourriez expérimenter des pertes ou des corruptions de données. Soyez très prudent et n’utilisez pas cela dans des environnements de production.</p>\n</aside>\n<p>Si vous devez faire cela depuis du code Python, faites-le avec <code class=\"docutils literal notranslate\">os.environ</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=\"nn\">os</span>\n\nos<span class=\"o\">.</span>environ<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>Fonctions d’adaptation asynchrone<a class=\"heading-anchor\" href=\"#async-adapter-functions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Il est nécessaire d’adapter le style d’appel lors des appels de code synchrone depuis un contexte asynchrone ou vice versa. Il existe pour cela deux fonctions d’adaptation dans le module <code class=\"docutils literal notranslate\">asgiref.sync</code>: <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\">async_to_sync()</code></a> et <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\">sync_to_async()</code></a>. Elles sont utiles pour faire le passage entre les styles d’appel tout en préservant la compatibilité.</p>\n<p>Ces fonctions d’adaptation sont largement utilisées dans Django. Le paquet <a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/asgiref/\">asgiref</a> lui-même fait partie du projet Django et il est automatiquement installé comme dépendance lorsqu’on installe Django avec <code class=\"docutils literal notranslate\">pip</code>.</p>\n<section id=\"async-to-sync\">\n<h3><code class=\"docutils literal notranslate\">async_to_sync()</code><a class=\"heading-anchor\" href=\"#async-to-sync\"><span class=\"visually-hidden\">Lien vers cette rubrique</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\">async_to_sync</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">async_function</em>, <em class=\"sig-param\">force_new_loop<span class=\"o\">=</span><span class=\"default_value\">False</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#asgiref.sync.async_to_sync\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Accepte une fonction asynchrone et renvoie une fonction synchrone qui l’enveloppe. Peut être utilisée sous forme directe ou comme décorateur</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=\"nn\">asgiref.sync</span> <span class=\"kn\">import</span> async_to_sync\n\n\n<span class=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">get_data</span><span class=\"p\">():</span> <span class=\"o\">...</span>\n\n\nsync_get_data <span class=\"o\">=</span> async_to_sync<span class=\"p\">(</span>get_data<span class=\"p\">)</span>\n\n\n<span class=\"nd\">@async_to_sync</span>\n<span class=\"k\">async</span> <span class=\"k\">def</span> <span class=\"nf\">get_other_data</span><span class=\"p\">():</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>La fonction asynchrone est exécutée dans la boucle événementielle du fil d’exécution actuel, le cas échéant. S’il n’y a pas de boucle événementielle, une nouvelle boucle est générée spécifiquement pour cette invocation asynchrone unique et arrêtée dès que la fonction est terminée. Quelle que soit la situation, la fonction asynchrone s’exécutera dans un fil d’exécution différent de celui du code appelant.</p>\n<p>Les valeurs « threadlocals » et « contextvars » sont préservées de part et d’autres des exécutions.</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\">async_to_sync()</code></a> est fondamentalement une version plus puissante de la fonction <a class=\"reference external\" href=\"https://docs.python.org/3/library/asyncio-runner.html#asyncio.run\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\">asyncio.run()</code></a> de la bibliothèque Python standard. En plus de s’assurer du fonctionnement de « threadlocals », elle active aussi le mode <code class=\"docutils literal notranslate\">thread_sensitive</code> de <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\">sync_to_async()</code></a> lorsque cette dernière est utilisée en dessous d’elle. À froid (sans boucle événementielle déjà lancée), elle paie le coût du démarrage d’une nouvelle boucle événementielle, comme pour <a class=\"reference external\" href=\"https://docs.python.org/3/library/asyncio-runner.html#asyncio.run\" title=\"(disponible dans Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\">asyncio.run()</code></a>; lorsqu’une telle boucle existe déjà (le cas dans une requête ASGI), la boucle est réutilisée et le coût s’allège donc d’autant.</p>\n</section>\n<section id=\"sync-to-async\">\n<h3><code class=\"docutils literal notranslate\">sync_to_async()</code><a class=\"heading-anchor\" href=\"#sync-to-async\"><span class=\"visually-hidden\">Lien vers cette rubrique</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\">sync_to_async</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">sync_function</em>, <em class=\"sig-param\">thread_sensitive<span class=\"o\">=</span><span class=\"default_value\">True</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#asgiref.sync.sync_to_async\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Accepte une fonction synchrone et renvoie une fonction asynchrone qui l’enveloppe. Peut être utilisée sous forme directe ou comme décorateur</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=\"nn\">asgiref.sync</span> <span class=\"kn\">import</span> sync_to_async\n\nasync_function <span class=\"o\">=</span> sync_to_async<span class=\"p\">(</span>sync_function<span class=\"p\">,</span> thread_sensitive<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\nasync_function <span class=\"o\">=</span> sync_to_async<span class=\"p\">(</span>sensitive_sync_function<span class=\"p\">,</span> thread_sensitive<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n\n<span class=\"nd\">@sync_to_async</span>\n<span class=\"k\">def</span> <span class=\"nf\">sync_function</span><span class=\"p\">():</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>Les valeurs « threadlocals » et « contextvars » sont préservées de part et d’autres des exécutions.</p>\n<p>Les fonctions synchrones ont tendances à être écrites en partant du principe qu’elles s’exécutent toutes dans le fil d’exécution principal, ce qui fait que <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\">sync_to_async()</code></a> dispose de deux modes d’exécution :</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">thread_sensitive=True</code> (valeur par défaut) : la fonction synchrone sera exécutée dans le même fil d’exécution que toutes les autres fonctions <code class=\"docutils literal notranslate\">thread_sensitive</code>. Ce fil sera le fil principal si celui-ci est synchrone et que vous utilisez la fonction enveloppeuse <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\">async_to_sync()</code></a>.</p></li>\n<li><p><code class=\"docutils literal notranslate\">thread_sensitive=False</code>: la fonction synchrone sera exécutée dans un tout nouveau fil d’exécution qui sera ensuite détruit lorsque l’invocation sera terminée.</p></li>\n</ul>\n<p>Le mode « thread-sensitive » est très spécial et fait beaucoup d’efforts pour exécuter toutes les fonctions dans le même fil d’exécution. Notez toutefois qu’il <em>compte sur l’utilisation de</em> <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\">async_to_sync()</code></a> <em>au-dessus de lui dans la pile d’appels</em> pour lancer les choses correctement dans le fil d’exécution principal. Si vous utilisez <code class=\"docutils literal notranslate\">asyncio.run()</code> ou une méthode semblable, il se limite à exécuter les fonctions dépendantes du fil d’exécution dans un seul fil partagé, mais il ne s’agira pas du fil d’exécution principal.</p>\n<p>La raison de sa présence dans Django est que de nombreuses bibliothèques, particulièrement les adaptateurs de base de données, exigent que leur accès se fasse dans le même fil d’exécution dans lequel elles ont été créées. De même, une grande quantité de code existant dans Django présuppose qu’il s’exécute entièrement dans le même fil d’exécution, par ex. un intergiciel ajoutant des éléments à une requête pour utilisation ultérieure dans les vues.</p>\n<p>Plutôt que d’introduire des problèmes potentiels de compatibilité avec ce code, nous avons choisi d’ajouter ce mode afin que tout code synchrone existant dans Django soit exécuté dans le même fil d’exécution et reste donc pleinement compatible avec le mode asynchrone. Notez que le code synchrone sera toujours exécuté dans un fil d’exécution <em>différent</em> du code asynchrone appelant, ce qui implique que vous devez éviter de passer des pointeurs bruts de base de données ou d’autres références sensibles au fil d’exécution.</p>\n<p>Dans une même requête, plusieurs appels <code class=\"docutils literal notranslate\">thread_sensitive</code> sont sérialisés sur le fil d’exécution actif de la requête, mais chaque requête reçoit sont propre fil par contexte, ce qui fait que les requêtes concurrentes ne sont <em>pas</em> sérialisées entre elles. Cela imite le modèle Django d’une « connexion par fil d’exécution », et la même contrainte s’applique dans d’autres bibliothèques de base de données asynchrones, où les requêtes concurrentes d’une seule connexion sont sérialisées sur un verrou. Pour prendre en charge plus de requêtes concurrentes, augmentez la taille du pool de connexions selon vos besoins plutôt que de désactiver <code class=\"docutils literal notranslate\">thread_sensitive</code>.</p>\n<p>En pratique, cette restriction signifie que vous ne devriez pas transmettre des fonctionnalités de l’objet de base de données <code class=\"docutils literal notranslate\">connection</code> lors de l’appel à <code class=\"docutils literal notranslate\">sync_to_async()</code>. Si vous le faites, cela déclenchera les contrôles de sécurité des fils d’exécution :</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=\"nn\">asyncio</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">asgiref.sync</span> <span class=\"kn\">import</span> sync_to_async\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> connection\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>connection<span class=\"o\">.</span>cursor<span class=\"p\">()</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> sync_to_async<span class=\"p\">(</span>connection<span class=\"o\">.</span>cursor<span class=\"p\">)()</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>Au lieu de cela, vous devriez encapsuler tous les accès à la base de données dans une fonction utilitaire pouvant être appelée par <code class=\"docutils literal notranslate\">sync_to_async()</code> sans vous baser sur l’objet de connexion dans le code appelant.</p>\n</section>\n</section>","rootId":"asynchronous-support","toc":[{"title":"Vues asynchrones","anchor":"async-views","children":[{"title":"Décorateurs","anchor":"decorators","children":[]},{"title":"Requêtes et ORM","anchor":"queries-the-orm","children":[]},{"title":"Performance","anchor":"performance","children":[]},{"title":"Gestion des déconnexions","anchor":"handling-disconnects","children":[]}]},{"title":"Isolation de code asynchrone","anchor":"async-safety","children":[]},{"title":"Fonctions d’adaptation asynchrone","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":"Utilisation de Django","url":"/fr/6.1/topics/"}],"prev":{"docname":"topics/checks","title":"Infrastructure de contrôle du système","url":"/fr/6.1/topics/checks/"},"next":{"docname":"topics/tasks","title":"L’infrastructure des tâches dans Django","url":"/fr/6.1/topics/tasks/"},"formats":{"html":"/fr/6.1/topics/async/","markdown":"/fr/6.1/topics/async.md","json":"/fr/6.1/topics/async.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/topics/async.txt","official":"https://docs.djangoproject.com/fr/6.1/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","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}