{"title":"Expressions de requête","version":"2.2","locale":"fr","docname":"ref/models/expressions","url":"/fr/2.2/ref/models/expressions/","canonical":"https://djangodocs.dev/fr/2.2/ref/models/expressions/","summary":"Les expressions de requête décrivent une valeur ou un calcul pouvant faire partie d’une mise à jour, d’une création, d’un filtre, d’un tri, d’une annotation…","html":"<h1>Expressions de requête<a class=\"heading-anchor\" href=\"#query-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Les expressions de requête décrivent une valeur ou un calcul pouvant faire partie d’une mise à jour, d’une création, d’un filtre, d’un tri, d’une annotation ou d’une agrégation. Il existe un certain nombre d’expressions intégrées (documentées ci-dessous) pouvant aider à construire des requêtes. Les expressions peuvent être combinées, ou même imbriquées dans certains cas, afin de former des calculs plus complexes.</p>\n<section id=\"supported-arithmetic\">\n<h2>Arithmétique prise en charge<a class=\"heading-anchor\" href=\"#supported-arithmetic\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django prend en charge la négation, l’addition, la soustraction, la multiplication, la division, l’arithmétique modulo ainsi que l’opérateur de puissance pour les expressions de requête, à l’aide de constantes Python, de variables et même d’autres expressions.</p>\n<aside class=\"version-note version-changed\" data-version=\"2.1\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 2.1</p><p>La prise en charge de la négation a été ajoutée.</p>\n</aside>\n</section>\n<section id=\"some-examples\">\n<h2>Quelques exemples<a class=\"heading-anchor\" href=\"#some-examples\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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 code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Count<span class=\"p\">,</span> F<span class=\"p\">,</span> Value\n<span class=\"kn\">from</span> <span class=\"nn\">django.db.models.functions</span> <span class=\"kn\">import</span> Length<span class=\"p\">,</span> Upper\n\n<span class=\"c1\"># Find companies that have more employees than chairs.</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>num_employees__gt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span>\n\n<span class=\"c1\"># Find companies that have at least twice as many employees</span>\n<span class=\"c1\"># as chairs. Both the querysets below are equivalent.</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>num_employees__gt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">)</span> <span class=\"o\">*</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n    num_employees__gt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span>\n\n<span class=\"c1\"># How many chairs are needed for each company to seat all employees?</span>\n<span class=\"o\">&gt;&gt;&gt;</span> company <span class=\"o\">=</span> Company<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n<span class=\"o\">...</span>    num_employees__gt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"o\">...</span>    chairs_needed<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;num_employees&#39;</span><span class=\"p\">)</span> <span class=\"o\">-</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span>first<span class=\"p\">()</span>\n<span class=\"o\">&gt;&gt;&gt;</span> company<span class=\"o\">.</span>num_employees\n<span class=\"mi\">120</span>\n<span class=\"o\">&gt;&gt;&gt;</span> company<span class=\"o\">.</span>num_chairs\n<span class=\"mi\">50</span>\n<span class=\"o\">&gt;&gt;&gt;</span> company<span class=\"o\">.</span>chairs_needed\n<span class=\"mi\">70</span>\n\n<span class=\"c1\"># Create a new company using expressions.</span>\n<span class=\"o\">&gt;&gt;&gt;</span> company <span class=\"o\">=</span> Company<span class=\"o\">.</span>objects<span class=\"o\">.</span>create<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s1\">&#39;Google&#39;</span><span class=\"p\">,</span> ticker<span class=\"o\">=</span>Upper<span class=\"p\">(</span>Value<span class=\"p\">(</span><span class=\"s1\">&#39;goog&#39;</span><span class=\"p\">)))</span>\n<span class=\"c1\"># Be sure to refresh it if you need to access the field.</span>\n<span class=\"o\">&gt;&gt;&gt;</span> company<span class=\"o\">.</span>refresh_from_db<span class=\"p\">()</span>\n<span class=\"o\">&gt;&gt;&gt;</span> company<span class=\"o\">.</span>ticker\n<span class=\"s1\">&#39;GOOG&#39;</span>\n\n<span class=\"c1\"># Annotate models with an aggregated value. Both forms</span>\n<span class=\"c1\"># below are equivalent.</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>num_products<span class=\"o\">=</span>Count<span class=\"p\">(</span><span class=\"s1\">&#39;products&#39;</span><span class=\"p\">))</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>num_products<span class=\"o\">=</span>Count<span class=\"p\">(</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;products&#39;</span><span class=\"p\">)))</span>\n\n<span class=\"c1\"># Aggregates can contain complex computations also</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>num_offerings<span class=\"o\">=</span>Count<span class=\"p\">(</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;products&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;services&#39;</span><span class=\"p\">)))</span>\n\n<span class=\"c1\"># Expressions can also be used in order_by(), either directly</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span>Length<span class=\"p\">(</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span>asc<span class=\"p\">())</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span>Length<span class=\"p\">(</span><span class=\"s1\">&#39;name&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span>desc<span class=\"p\">())</span>\n<span class=\"c1\"># or using the double underscore lookup syntax.</span>\n<span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> CharField\n<span class=\"kn\">from</span> <span class=\"nn\">django.db.models.functions</span> <span class=\"kn\">import</span> Length\nCharField<span class=\"o\">.</span>register_lookup<span class=\"p\">(</span>Length<span class=\"p\">)</span>\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s1\">&#39;name__length&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"built-in-expressions\">\n<h2>Expressions intégrées<a class=\"heading-anchor\" href=\"#built-in-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Ces expressions sont définies dans <code class=\"docutils literal notranslate\">django.db.models.expressions</code> et <code class=\"docutils literal notranslate\">django.db.models.aggregates</code>, mais par commodité elles sont disponibles et habituellement importées à partir de <a class=\"reference internal\" href=\"/fr/2.2/topics/db/models/#module-django.db.models\" title=\"django.db.models\"><code class=\"xref py py-mod docutils literal notranslate\">django.db.models</code></a>.</p>\n</aside>\n<section id=\"f-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\">F()</code><a class=\"heading-anchor\" href=\"#f-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.F\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">F</span><a class=\"heading-anchor\" href=\"#django.db.models.F\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un objet <code class=\"docutils literal notranslate\">F()</code> représente la valeur d’un champ de modèle ou d’une colonne annotée. Il permet de se référer à des valeurs de champs de modèles et d’effectuer avec elles des opérations en base de données sans avoir à les récupérer préalablement de la base de données vers la mémoire Python.</p>\n<p>Au lieu de cela, Django utilise un objet <code class=\"docutils literal notranslate\">F()</code> pour générer une expression SQL qui décrit l’opération requise au niveau de la base de données.</p>\n<p>Il est plus simple de faire comprendre cela par un exemple. Normalement, on peut faire quelque chose comme ceci :</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=\"c1\"># Tintin filed a news story!</span>\nreporter <span class=\"o\">=</span> Reporters<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s1\">&#39;Tintin&#39;</span><span class=\"p\">)</span>\nreporter<span class=\"o\">.</span>stories_filed <span class=\"o\">+=</span> <span class=\"mi\">1</span>\nreporter<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>Ici, nous avons obtenu en mémoire la valeur de <code class=\"docutils literal notranslate\">reporter.stories_filed</code> à partir de la base de données et nous l’avons manipulée avec des opérateurs Python familiers. Nous avons ensuite enregistré l’objet modifié en base de données. Cependant, nous aurions tout aussi bien pu écrire :</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.db.models</span> <span class=\"kn\">import</span> F\n\nreporter <span class=\"o\">=</span> Reporters<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s1\">&#39;Tintin&#39;</span><span class=\"p\">)</span>\nreporter<span class=\"o\">.</span>stories_filed <span class=\"o\">=</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;stories_filed&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\nreporter<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p>Même si <code class=\"docutils literal notranslate\">reporter.stories_filed = F('stories_filed') + 1</code> apparaît comme une attribution normale de valeur à un attribut d’instance en Python, il s’agit en réalité d’une construction SQL décrivant une opération en base de données.</p>\n<p>Lorsque Django rencontre une instance de <code class=\"docutils literal notranslate\">F()</code>, il surcharge les opérateurs Python standards pour créer une expression SQL encapsulée ; dans ce cas, une instruction qui demande à la base de données d’incrémenter le champ de base de données représenté par <code class=\"docutils literal notranslate\">reporter.stories_filed</code>.</p>\n<p>Quelle que soit la valeur que contenait <code class=\"docutils literal notranslate\">reporter.stories_filed</code>, Python n’a jamais besoin de la connaître, car tout se passe en base de données. Tout ce que Python fait à travers la classe <code class=\"docutils literal notranslate\">F()</code> de Django est de créer la syntaxe SQL pour se référer au champ et décrire l’opération.</p>\n<p>Pour accéder à la nouvelle valeur qui a été enregistrée de cette manière, l’objet doit être rechargé :</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>reporter <span class=\"o\">=</span> Reporters<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>pk<span class=\"o\">=</span>reporter<span class=\"o\">.</span>pk<span class=\"p\">)</span>\n<span class=\"c1\"># Or, more succinctly:</span>\nreporter<span class=\"o\">.</span>refresh_from_db<span class=\"p\">()</span>\n</code></pre></div>\n<p>En plus d’être utilisée dans les opérations sur des instances uniques comme ci-dessus, <code class=\"docutils literal notranslate\">F()</code> peut être utilisée sur des jeux <code class=\"docutils literal notranslate\">QuerySets</code> d’instances d’objets, avec <code class=\"docutils literal notranslate\">update()</code>. Cela permet de réduire les deux requêtes utilisées ci-dessus, <code class=\"docutils literal notranslate\">get()</code> et <a class=\"reference internal\" href=\"/fr/2.2/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a>, à une seule :</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>reporter <span class=\"o\">=</span> Reporters<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s1\">&#39;Tintin&#39;</span><span class=\"p\">)</span>\nreporter<span class=\"o\">.</span>update<span class=\"p\">(</span>stories_filed<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;stories_filed&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Nous pouvons aussi utiliser <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.update\" title=\"django.db.models.query.QuerySet.update\"><code class=\"xref py py-meth docutils literal notranslate\">update()</code></a> pour incrémenter la valeur du champ sur plusieurs objets, ce qui peut être beaucoup plus rapide que de récupérer toutes les valeurs en Python depuis la base de données, de les passer en boucle en incrémentant la valeur des champs pour chacun, et de les réenregistrer individuellement dans la base de données :</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>Reporter<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span><span class=\"o\">.</span>update<span class=\"p\">(</span>stories_filed<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;stories_filed&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">F()</code> peut donc offrir des avantages de performance en :</p>\n<ul class=\"simple\">\n<li><p>faisant travailler la base de données plutôt que le code Python ;</p></li>\n<li><p>réduisant le nombre de requêtes de certaines opérations.</p></li>\n</ul>\n<section id=\"avoiding-race-conditions-using-f\">\n<span id=\"id1\"></span><h4>Prévention des conflits de concurrence avec <code class=\"docutils literal notranslate\">F()</code><a class=\"heading-anchor\" href=\"#avoiding-race-conditions-using-f\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Un autre bénéfice notable de <code class=\"docutils literal notranslate\">F()</code> est que de faire mettre à jour la valeur d’un champ par la base de données plutôt qu’en Python évite un <em>conflit de concurrence</em>.</p>\n<p>Si deux fils d’exécution Python exécutent le code du premier exemple ci-dessus, un des fils pourrait obtenir, incrémenter et enregistrer une valeur de champ après que l’autre fil l’ait obtenu de la base de données. La valeur enregistrée par le second fil d’exécution sera basé sur la valeur d’origine ; le travail du premier fil d’exécution sera tout simplement perdu.</p>\n<p>Si c’est la base de données qui est responsable de la mise à jour du champ, le processus est plus robuste : la valeur du champ sera toujours mise à jour en fonction de sa valeur en base de données au moment même de l’appel à <a class=\"reference internal\" href=\"/fr/2.2/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</code></a> ou <code class=\"docutils literal notranslate\">update()</code>, et non pas en fonction de la valeur obtenue au moment de la création de l’instance de modèle.</p>\n</section>\n<section id=\"f-assignments-persist-after-model-save\">\n<h4>Les attributions par <code class=\"docutils literal notranslate\">F()</code> persistent après <code class=\"docutils literal notranslate\">Model.save()</code><a class=\"heading-anchor\" href=\"#f-assignments-persist-after-model-save\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Les objets <code class=\"docutils literal notranslate\">F()</code> attribués aux champs de modèles persistent après l’enregistrement de l’instance de modèle et seront appliqués pour chaque <a class=\"reference internal\" href=\"/fr/2.2/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\">save()</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>reporter <span class=\"o\">=</span> Reporters<span class=\"o\">.</span>objects<span class=\"o\">.</span>get<span class=\"p\">(</span>name<span class=\"o\">=</span><span class=\"s1\">&#39;Tintin&#39;</span><span class=\"p\">)</span>\nreporter<span class=\"o\">.</span>stories_filed <span class=\"o\">=</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;stories_filed&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span>\nreporter<span class=\"o\">.</span>save<span class=\"p\">()</span>\n\nreporter<span class=\"o\">.</span>name <span class=\"o\">=</span> <span class=\"s1\">&#39;Tintin Jr.&#39;</span>\nreporter<span class=\"o\">.</span>save<span class=\"p\">()</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">stories_filed</code> sera mis à jour deux fois dans ce cas. SI la valeur initiale est <code class=\"docutils literal notranslate\">1</code>, la valeur finale sera <code class=\"docutils literal notranslate\">3</code>. Cette persistance peut être évitée en rechargeant le modèle après son enregistrement, par exemple en utilisant <a class=\"reference internal\" href=\"/fr/2.2/ref/models/instances/#django.db.models.Model.refresh_from_db\" title=\"django.db.models.Model.refresh_from_db\"><code class=\"xref py py-meth docutils literal notranslate\">refresh_from_db()</code></a>.</p>\n</section>\n<section id=\"using-f-in-filters\">\n<h4>Utilisation de <code class=\"docutils literal notranslate\">F()</code> dans les filtres<a class=\"heading-anchor\" href=\"#using-f-in-filters\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><code class=\"docutils literal notranslate\">F()</code> est aussi très utile dans les filtres <code class=\"docutils literal notranslate\">QuerySet</code>, là où il est possible de filtrer un jeu d’objets en fonction de critères basés sur les valeurs des champs, plutôt que sur des valeurs Python.</p>\n<p>Cette utilisation est documentée dans <a class=\"reference internal\" href=\"/fr/2.2/topics/db/queries/#using-f-expressions-in-filters\"><span class=\"std std-ref\">Expressions F() dans les requêtes</span></a>.</p>\n</section>\n<section id=\"using-f-with-annotations\">\n<span id=\"id2\"></span><h4>Utilisation de <code class=\"docutils literal notranslate\">F()</code> avec les annotations<a class=\"heading-anchor\" href=\"#using-f-with-annotations\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><code class=\"docutils literal notranslate\">F()</code> peut être utilisée pour créer des champs dynamiques pour les modèles en combinant plusieurs champs de manière arithmétique :</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>company <span class=\"o\">=</span> Company<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n    chairs_needed<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;num_employees&#39;</span><span class=\"p\">)</span> <span class=\"o\">-</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;num_chairs&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Si les champs que vous combinez sont de types différents, il est nécessaire d’indiquer à Django le type de champ qui en résultera. Comme <code class=\"docutils literal notranslate\">F()</code> ne prend pas directement en charge <code class=\"docutils literal notranslate\">output_field</code>, il faut envelopper l’expression dans <a class=\"reference internal\" href=\"#django.db.models.ExpressionWrapper\" title=\"django.db.models.ExpressionWrapper\"><code class=\"xref py py-class docutils literal notranslate\">ExpressionWrapper</code></a>:</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.db.models</span> <span class=\"kn\">import</span> DateTimeField<span class=\"p\">,</span> ExpressionWrapper<span class=\"p\">,</span> F\n\nTicket<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n    expires<span class=\"o\">=</span>ExpressionWrapper<span class=\"p\">(</span>\n        F<span class=\"p\">(</span><span class=\"s1\">&#39;active_at&#39;</span><span class=\"p\">)</span> <span class=\"o\">+</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;duration&#39;</span><span class=\"p\">),</span> output_field<span class=\"o\">=</span>DateTimeField<span class=\"p\">()))</span>\n</code></pre></div>\n<p>Lorsqu’elle fait référence à des champs relationnels tels qu’une clé <code class=\"docutils literal notranslate\">ForeignKey</code>, <code class=\"docutils literal notranslate\">F()</code> renvoie la valeur de clé primaire plutôt qu’une instance de modèle :</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\">&gt;&gt;</span> car <span class=\"o\">=</span> Company<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>built_by<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;manufacturer&#39;</span><span class=\"p\">))[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"o\">&gt;&gt;</span> car<span class=\"o\">.</span>manufacturer\n<span class=\"o\">&lt;</span>Manufacturer<span class=\"p\">:</span> Toyota<span class=\"o\">&gt;</span>\n<span class=\"o\">&gt;&gt;</span> car<span class=\"o\">.</span>built_by\n<span class=\"mi\">3</span>\n</code></pre></div>\n</section>\n<section id=\"using-f-to-sort-null-values\">\n<span id=\"id3\"></span><h4>Utilisation de <code class=\"docutils literal notranslate\">F()</code> pour trier les valeurs nulles<a class=\"heading-anchor\" href=\"#using-f-to-sort-null-values\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Utilisez <code class=\"docutils literal notranslate\">F()</code> et les paramètres nommés <code class=\"docutils literal notranslate\">nulls_first</code> ou <code class=\"docutils literal notranslate\">nulls_last</code> des expressions <a class=\"reference internal\" href=\"#django.db.models.Expression.asc\" title=\"django.db.models.Expression.asc\"><code class=\"xref py py-meth docutils literal notranslate\">Expression.asc()</code></a> ou <a class=\"reference internal\" href=\"#django.db.models.Expression.desc\" title=\"django.db.models.Expression.desc\"><code class=\"xref py py-meth docutils literal notranslate\">desc()</code></a> pour contrôler le tri des valeurs nulles d’un champ. Par défaut, l’ordre dépend de la base de données.</p>\n<p>Par exemple, pour trier les entreprises qui n’ont pas été contactées (<code class=\"docutils literal notranslate\">last_contacted</code> est nul) après les entreprises qui ont été contactées</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.db.models</span> <span class=\"kn\">import</span> F\nCompany<span class=\"o\">.</span>object<span class=\"o\">.</span>order_by<span class=\"p\">(</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;last_contacted&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span>desc<span class=\"p\">(</span>nulls_last<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">))</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"func-expressions\">\n<span id=\"id4\"></span><h3>Expressions <code class=\"docutils literal notranslate\">Func()</code><a class=\"heading-anchor\" href=\"#func-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les expressions <code class=\"docutils literal notranslate\">Func()</code> sont le type de base de toutes les expressions qui impliquent des fonctions de base de données telles que <code class=\"docutils literal notranslate\">COALESCE</code> et <code class=\"docutils literal notranslate\">LOWER</code>, ou des agrégations comme <code class=\"docutils literal notranslate\">SUM</code>. Elles peuvent être utilisées directement :</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.db.models</span> <span class=\"kn\">import</span> F<span class=\"p\">,</span> Func\n\nqueryset<span class=\"o\">.</span>annotate<span class=\"p\">(</span>field_lower<span class=\"o\">=</span>Func<span class=\"p\">(</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;field&#39;</span><span class=\"p\">),</span> function<span class=\"o\">=</span><span class=\"s1\">&#39;LOWER&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>ou elles peuvent être utilisées pour bâtir une bibliothèque de fonctions de base de données :</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\">Lower</span><span class=\"p\">(</span>Func<span class=\"p\">):</span>\n    function <span class=\"o\">=</span> <span class=\"s1\">&#39;LOWER&#39;</span>\n\nqueryset<span class=\"o\">.</span>annotate<span class=\"p\">(</span>field_lower<span class=\"o\">=</span>Lower<span class=\"p\">(</span><span class=\"s1\">&#39;field&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>Mais dans les deux cas, chaque modèle du jeu de requête résultant sera annoté avec un attribut supplémentaire <code class=\"docutils literal notranslate\">field_lower</code> dont le contenu correspondra plus ou moins au code SQL suivant :</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>SELECT\n    <span class=\"o\">...</span>\n    LOWER<span class=\"p\">(</span><span class=\"s2\">&quot;db_table&quot;</span><span class=\"o\">.</span><span class=\"s2\">&quot;field&quot;</span><span class=\"p\">)</span> <span class=\"k\">as</span> <span class=\"s2\">&quot;field_lower&quot;</span>\n</code></pre></div>\n<p>Voir <a class=\"reference internal\" href=\"/fr/2.2/ref/models/database-functions/\"><span class=\"doc\">Fonctions de base de données</span></a> pour une liste de fonctions de base de données intégrées.</p>\n<p>L’API <code class=\"docutils literal notranslate\">Func</code> se présente comme suit :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Func</span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\">*</span>expressions</em>, <em class=\"sig-param\"><span class=\"o\">**</span>extra</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Func\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.function\">\n<span class=\"sig-name descname\">function</span><a class=\"heading-anchor\" href=\"#django.db.models.Func.function\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe décrivant la fonction qui sera générée. Plus précisément, <code class=\"docutils literal notranslate\">function</code> sera inséré par le substituant <code class=\"docutils literal notranslate\">function</code> à l’intérieur de <a class=\"reference internal\" href=\"#django.db.models.Func.template\" title=\"django.db.models.Func.template\"><code class=\"xref py py-attr docutils literal notranslate\">template</code></a>. Sa valeur par défaut est <code class=\"docutils literal notranslate\">None</code>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.template\">\n<span class=\"sig-name descname\">template</span><a class=\"heading-anchor\" href=\"#django.db.models.Func.template\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe, sous forme de chaîne de format, qui décrit le code SQL généré pour cette fonction. Sa valeur par défaut est <code class=\"docutils literal notranslate\">'%(function)s(%(expressions)s)'</code>.</p>\n<p>SI vous construisez du code SQL tel que <code class=\"docutils literal notranslate\">strftime('%W', 'date')</code> et que vous avez besoin d’un caractère littéral <code class=\"docutils literal notranslate\">%</code> dans la requête, vous devez le quadrupler (<code class=\"docutils literal notranslate\">%%%%</code>) dans l’attribut <code class=\"docutils literal notranslate\">template</code> car la chaîne est interpolée deux fois : une fois pendant l’interpolation du gabarit dans <code class=\"docutils literal notranslate\">as_sql()</code>, et une autre fois dans l’interpolation SQL avec les paramètres de requête dans le curseur de base de données.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.arg_joiner\">\n<span class=\"sig-name descname\">arg_joiner</span><a class=\"heading-anchor\" href=\"#django.db.models.Func.arg_joiner\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe qui précise la séquence de caractères utilisée pour joindre les éléments de la liste d”<code class=\"docutils literal notranslate\">expressions</code>. Sa valeur par défaut est <code class=\"docutils literal notranslate\">', '</code>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.arity\">\n<span class=\"sig-name descname\">arity</span><a class=\"heading-anchor\" href=\"#django.db.models.Func.arity\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe qui indique le nombre de paramètres acceptés par la fonction. Si cet attribut est défini et que la fonction est appelée avec un nombre d’expressions différent, une exception <code class=\"docutils literal notranslate\">TypeError</code> sera générée. La valeur par défaut est <code class=\"docutils literal notranslate\">None</code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Func.as_sql\">\n<span class=\"sig-name descname\">as_sql</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">compiler</em>, <em class=\"sig-param\">connection</em>, <em class=\"sig-param\">function<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">template<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">arg_joiner<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\"><span class=\"o\">**</span>extra_context</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Func.as_sql\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Produit le code SQL pour la fonction de base de données.</p>\n<p>Les méthodes <code class=\"docutils literal notranslate\">as_vendor()</code> devraient utiliser les paramètres <code class=\"docutils literal notranslate\">function</code>, <code class=\"docutils literal notranslate\">template</code>, <code class=\"docutils literal notranslate\">arg_joiner</code> et tout autre paramètre <code class=\"docutils literal notranslate\">**extra_context</code> pour adapter le code SQL en cas de besoin. Par exemple :</p>\n<figure class=\"code-block code-block-captioned\" data-language=\"python\"><figcaption class=\"code-block-caption\">django/db/models/functions.py</figcaption>\n<div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</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 code\"><code><span class=\"k\">class</span> <span class=\"nc\">ConcatPair</span><span class=\"p\">(</span>Func<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    function <span class=\"o\">=</span> <span class=\"s1\">&#39;CONCAT&#39;</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">as_mysql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> compiler<span class=\"p\">,</span> connection<span class=\"p\">,</span> <span class=\"o\">**</span>extra_context<span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>as_sql<span class=\"p\">(</span>\n            compiler<span class=\"p\">,</span> connection<span class=\"p\">,</span>\n            function<span class=\"o\">=</span><span class=\"s1\">&#39;CONCAT_WS&#39;</span><span class=\"p\">,</span>\n            template<span class=\"o\">=</span><span class=\"s2\">&quot;</span><span class=\"si\">%(function)s</span><span class=\"s2\">(&#39;&#39;, </span><span class=\"si\">%(expressions)s</span><span class=\"s2\">)&quot;</span><span class=\"p\">,</span>\n            <span class=\"o\">**</span>extra_context\n        <span class=\"p\">)</span>\n</code></pre></figure>\n<p>Pour éviter une vulnérabilité d’injection SQL, <code class=\"docutils literal notranslate\">extra_context</code> <a class=\"reference internal\" href=\"#avoiding-sql-injection-in-query-expressions\"><span class=\"std std-ref\">ne doit pas contenir de contenu non sûr provenant des utilisateurs</span></a> car ces valeurs sont insérées dans la chaîne SQL et non passées comme paramètres de requête, auquel cas le pilote de base de données les aurait échappés.</p>\n</dd></dl>\n\n</dd></dl>\n\n<p>Le paramètre <code class=\"docutils literal notranslate\">*expressions</code> est une liste d’expressions positionnelles auxquelles la fonction s’applique. Les expressions sont converties en chaînes, jointes par <code class=\"docutils literal notranslate\">arg_joiner</code>, puis insérées dans <code class=\"docutils literal notranslate\">template</code> par le substituant <code class=\"docutils literal notranslate\">expressions</code>.</p>\n<p>Les paramètres positionnels peuvent être des expressions ou des valeurs Python. Les chaînes sont censées être des références de colonnes et seront enveloppées dans des expressions <code class=\"docutils literal notranslate\">F()</code> alors que les autres valeurs sont enveloppées dans des expressions <code class=\"docutils literal notranslate\">Value()</code>.</p>\n<p>Les paramètres nommés <code class=\"docutils literal notranslate\">**extra</code> sont des paires <code class=\"docutils literal notranslate\">clé=valeur</code> qui peuvent être insérées dans l’attribut <code class=\"docutils literal notranslate\">template</code>. Pour éviter une vulnérabilité d’injection SQL, <code class=\"docutils literal notranslate\">extra</code> <a class=\"reference internal\" href=\"#avoiding-sql-injection-in-query-expressions\"><span class=\"std std-ref\">ne doit pas contenir de contenu non sûr provenant des utilisateurs</span></a> car ces valeurs sont insérées dans la chaîne SQL et non passées comme paramètres de requête, auquel cas le pilote de base de données les aurait échappés.</p>\n<p>Les mots-clés <code class=\"docutils literal notranslate\">function</code>, <code class=\"docutils literal notranslate\">template</code> et <code class=\"docutils literal notranslate\">arg_joiner</code> peuvent être utilisés pour remplacer les attributs de même nom sans avoir besoin de définir une classe spécifique. <code class=\"docutils literal notranslate\">output_field</code> peut être utilisé pour définir le type de la valeur renvoyée.</p>\n</section>\n<section id=\"aggregate-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\">Aggregate()</code><a class=\"heading-anchor\" href=\"#aggregate-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Une expression d’agrégation est un cas particulier d’une <a class=\"reference internal\" href=\"#func-expressions\"><span class=\"std std-ref\">expression Func()</span></a> qui informe la requête qu’une clause <code class=\"docutils literal notranslate\">GROUP BY</code> est nécessaire. Toutes les <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#aggregation-functions\"><span class=\"std std-ref\">fonctions d’agrégation</span></a> comme <code class=\"docutils literal notranslate\">Sum()</code> et <code class=\"docutils literal notranslate\">Count()</code> héritent de <code class=\"docutils literal notranslate\">Aggregate()</code>.</p>\n<p>Comme les <code class=\"docutils literal notranslate\">Aggregate</code> sont des des expressions et enveloppent des expressions, il est possible de représenter des calculs complexes :</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.db.models</span> <span class=\"kn\">import</span> Count\n\nCompany<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n    managers_required<span class=\"o\">=</span><span class=\"p\">(</span>Count<span class=\"p\">(</span><span class=\"s1\">&#39;num_employees&#39;</span><span class=\"p\">)</span> <span class=\"o\">/</span> <span class=\"mi\">4</span><span class=\"p\">)</span> <span class=\"o\">+</span> Count<span class=\"p\">(</span><span class=\"s1\">&#39;num_managers&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>L’API <code class=\"docutils literal notranslate\">Aggregate</code> se présente comme suit :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Aggregate\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Aggregate</span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"o\">*</span>expressions</em>, <em class=\"sig-param\">output_field<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">distinct<span class=\"o\">=</span><span class=\"default_value\">False</span></em>, <em class=\"sig-param\">filter<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\"><span class=\"o\">**</span>extra</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Aggregate\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Aggregate.template\">\n<span class=\"sig-name descname\">template</span><a class=\"heading-anchor\" href=\"#django.db.models.Aggregate.template\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe, sous forme de chaîne de format, qui décrit le code SQL généré pour cette agrégation. Sa valeur par défaut est <code class=\"docutils literal notranslate\">'%(function)s(%(distinct)s%(expressions)s)'</code>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Aggregate.function\">\n<span class=\"sig-name descname\">function</span><a class=\"heading-anchor\" href=\"#django.db.models.Aggregate.function\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut de classe décrivant la fonction d’agrégation qui sera générée. Plus précisément, <code class=\"docutils literal notranslate\">function</code> sera inséré par le substituant <code class=\"docutils literal notranslate\">function</code> à l’intérieur de <a class=\"reference internal\" href=\"#django.db.models.Aggregate.template\" title=\"django.db.models.Aggregate.template\"><code class=\"xref py py-attr docutils literal notranslate\">template</code></a>. Sa valeur par défaut est <code class=\"docutils literal notranslate\">None</code>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Aggregate.window_compatible\">\n<span class=\"sig-name descname\">window_compatible</span><a class=\"heading-anchor\" href=\"#django.db.models.Aggregate.window_compatible\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Vaut <code class=\"docutils literal notranslate\">True</code> par défaut car la plupart des fonctions d’agrégat peuvent être utilisées comme expression source dans <a class=\"reference internal\" href=\"#django.db.models.expressions.Window\" title=\"django.db.models.expressions.Window\"><code class=\"xref py py-class docutils literal notranslate\">Window</code></a>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Aggregate.allow_distinct\">\n<span class=\"sig-name descname\">allow_distinct</span><a class=\"heading-anchor\" href=\"#django.db.models.Aggregate.allow_distinct\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><aside class=\"version-note version-added\" data-version=\"2.2\" role=\"note\">\n<p class=\"version-note-title\">New in Django 2.2</p></aside>\n<p>Un attribut de classe déterminant si cette fonction d’agrégat permet de passer un paramètre nommé <code class=\"docutils literal notranslate\">distinct</code>. Si défini à <code class=\"docutils literal notranslate\">False</code> (par défaut), <code class=\"docutils literal notranslate\">TypeError</code> est générée si <code class=\"docutils literal notranslate\">distinct=True</code> est transmis.</p>\n</dd></dl>\n\n</dd></dl>\n\n<p>Les paramètres positionnels <code class=\"docutils literal notranslate\">expressions</code> peuvent inclure des expressions ou des noms de champs de modèle. Ils seront convertis en texte et utilisé comme substituant <code class=\"docutils literal notranslate\">expressions</code> à l’intérieur de <code class=\"docutils literal notranslate\">template</code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">output_field</code> doit être une instance de champ de modèle, comme <code class=\"docutils literal notranslate\">IntegerField()</code> ou <code class=\"docutils literal notranslate\">BooleanField()</code>, dans laquelle Django chargera la valeur après qu’elle aura été reçue de la base de données. Aucun paramètre n’est habituellement nécessaire lors de la création de l’instance du champ de modèle car aucun paramètre lié à la validation de données (<code class=\"docutils literal notranslate\">max_length</code>, <code class=\"docutils literal notranslate\">max_digits</code>, etc.) ne sera appliqué à la valeur résultante de l’expression.</p>\n<p>Notez que <code class=\"docutils literal notranslate\">output_field</code> n’est obligatoire que lorsque Django est incapable de déterminer le type de champ du résultat. Les expressions complexes qui mélangent des types de champs doivent définir avec <code class=\"docutils literal notranslate\">output_field</code> le type de résultat attendu. Par exemple, l’addition d’un <code class=\"docutils literal notranslate\">IntegerField()</code> et d’un <code class=\"docutils literal notranslate\">FloatField()</code> va probablement demander la définition de <code class=\"docutils literal notranslate\">output_field=FloatField()</code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">distinct</code> détermine si la fonction d’agrégat doit être invoquée pour chaque valeur distincte de <code class=\"docutils literal notranslate\">expressions</code> (ou ensemble de valeurs, en cas d’expressions multiples). Le paramètre n’est pris en charge que pour les agrégats qui possèdent <a class=\"reference internal\" href=\"#django.db.models.Aggregate.allow_distinct\" title=\"django.db.models.Aggregate.allow_distinct\"><code class=\"xref py py-attr docutils literal notranslate\">allow_distinct</code></a> à <code class=\"docutils literal notranslate\">True</code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">filter</code> accepte un <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.Q\" title=\"django.db.models.Q\"><code class=\"xref py py-class docutils literal notranslate\">objet Q</code></a> utilisé pour filtrer les lignes agrégées. Voir <a class=\"reference internal\" href=\"/fr/2.2/ref/models/conditional-expressions/#conditional-aggregation\"><span class=\"std std-ref\">Agrégation conditionnelle</span></a> et <a class=\"reference internal\" href=\"/fr/2.2/topics/db/aggregation/#filtering-on-annotations\"><span class=\"std std-ref\">Filtrage sur les annotations</span></a> pour des exemples d’utilisation.</p>\n<p>Les paramètres nommés <code class=\"docutils literal notranslate\">**extra</code> sont des paires <code class=\"docutils literal notranslate\">clé=valeur</code> qui peuvent être insérées par interpolation dans l’attribut <code class=\"docutils literal notranslate\">template</code>.</p>\n<aside class=\"version-note version-added\" data-version=\"2.2\" role=\"note\">\n<p class=\"version-note-title\">New in Django 2.2</p><p>Les paramètres <code class=\"docutils literal notranslate\">allow_distinct</code> et <code class=\"docutils literal notranslate\">distinct</code> ont été ajoutés.</p>\n</aside>\n</section>\n<section id=\"creating-your-own-aggregate-functions\">\n<h3>Création de ses propres fonctions d’agrégation<a class=\"heading-anchor\" href=\"#creating-your-own-aggregate-functions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La création de ses propres agrégations est très facile. Il faut définir au minimum <code class=\"docutils literal notranslate\">function</code>, mais vous pouvez aussi personnaliser complètement le code SQL produit. Voici un court 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.db.models</span> <span class=\"kn\">import</span> Aggregate\n\n<span class=\"k\">class</span> <span class=\"nc\">Sum</span><span class=\"p\">(</span>Aggregate<span class=\"p\">):</span>\n    <span class=\"c1\"># Supports SUM(ALL field).</span>\n    function <span class=\"o\">=</span> <span class=\"s1\">&#39;SUM&#39;</span>\n    template <span class=\"o\">=</span> <span class=\"s1\">&#39;</span><span class=\"si\">%(function)s</span><span class=\"s1\">(</span><span class=\"si\">%(all_values)s%(expressions)s</span><span class=\"s1\">)&#39;</span>\n    allow_distinct <span class=\"o\">=</span> <span class=\"kc\">False</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> expression<span class=\"p\">,</span> all_values<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> <span class=\"o\">**</span>extra<span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span>\n            expression<span class=\"p\">,</span>\n            all_values<span class=\"o\">=</span><span class=\"s1\">&#39;ALL &#39;</span> <span class=\"k\">if</span> all_values <span class=\"k\">else</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n            <span class=\"o\">**</span>extra\n        <span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"value-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\">Value()</code><a class=\"heading-anchor\" href=\"#value-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Value\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Value</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">value</em>, <em class=\"sig-param\">output_field<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Value\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Un objet <code class=\"docutils literal notranslate\">Value()</code> représente le composant le plus petit possible d’une expression : une simple valeur. Lorsque vous avez besoin de représenter la valeur d’un nombre entier, d’un booléen ou d’une chaîne à l’intérieur d’une expression, vous pouvez insérer cette valeur dans un objet <code class=\"docutils literal notranslate\">Value()</code>.</p>\n<p>Il est rarement nécessaire de faire appel directement à <code class=\"docutils literal notranslate\">Value()</code>. Lorsque vous écrivez l’expression <code class=\"docutils literal notranslate\">F('champ') + 1</code>, Django insère implicitement le <code class=\"docutils literal notranslate\">1</code> dans un objet <code class=\"docutils literal notranslate\">Value()</code>, ce qui permet d’utiliser des valeurs simples dans des expressions plus complexes. <code class=\"docutils literal notranslate\">Value()</code> devra être utilisé lors du passage d’une chaîne à une expression. La plupart des expressions interprètent un paramètre textuel comme le nom d’un champ, comme par exemple <code class=\"docutils literal notranslate\">Lower('name')</code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">value</code> décrit la valeur à inclure dans l’expression, comme <code class=\"docutils literal notranslate\">1</code>, <code class=\"docutils literal notranslate\">True</code> ou <code class=\"docutils literal notranslate\">None</code>. Django sait comment convertir ces valeurs Python dans le bon type de la base de données correspondante.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">output_field</code> doit être une instance de champ de modèle, comme <code class=\"docutils literal notranslate\">IntegerField()</code> ou <code class=\"docutils literal notranslate\">BooleanField()</code>, dans laquelle Django chargera la valeur après qu’elle aura été reçue de la base de données. Aucun paramètre n’est habituellement nécessaire lors de la création de l’instance du champ de modèle car aucun paramètre lié à la validation de données (<code class=\"docutils literal notranslate\">max_length</code>, <code class=\"docutils literal notranslate\">max_digits</code>, etc.) ne sera appliqué à la valeur résultante de l’expression.</p>\n</section>\n<section id=\"expressionwrapper-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\">ExpressionWrapper()</code><a class=\"heading-anchor\" href=\"#expressionwrapper-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.ExpressionWrapper\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">ExpressionWrapper</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">expression</em>, <em class=\"sig-param\">output_field</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.ExpressionWrapper\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\">ExpressionWrapper</code> ne fait qu’entourer une autre expression et permet d’accéder aux propriétés, telles que <code class=\"docutils literal notranslate\">output_field</code>, qui pourraient ne pas être disponibles dans d’autres expressions. <code class=\"docutils literal notranslate\">ExpressionWrapper</code> est nécessaire lorsqu’on utilise de l’arithmétique avec les expressions <code class=\"docutils literal notranslate\">F()</code> avec différents types, comme décrit dans <a class=\"reference internal\" href=\"#using-f-with-annotations\"><span class=\"std std-ref\">Utilisation de F() avec les annotations</span></a>.</p>\n</section>\n<section id=\"conditional-expressions\">\n<h3>Expressions conditionnelles<a class=\"heading-anchor\" href=\"#conditional-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les expressions conditionnelles permettent d’utiliser de la logique <a class=\"reference external\" href=\"https://docs.python.org/3/reference/compound_stmts.html#if\" title=\"(disponible dans Python v3.14)\"><code class=\"xref std std-keyword docutils literal notranslate\">if</code></a> … <a class=\"reference external\" href=\"https://docs.python.org/3/reference/compound_stmts.html#elif\" title=\"(disponible dans Python v3.14)\"><code class=\"xref std std-keyword docutils literal notranslate\">elif</code></a> … <a class=\"reference external\" href=\"https://docs.python.org/3/reference/compound_stmts.html#else\" title=\"(disponible dans Python v3.14)\"><code class=\"xref std std-keyword docutils literal notranslate\">else</code></a> dans les requêtes. Django prend nativement en charge les expressions SQL <code class=\"docutils literal notranslate\">CASE</code>. Pour plus de détails, consultez <a class=\"reference internal\" href=\"/fr/2.2/ref/models/conditional-expressions/\"><span class=\"doc\">Expressions conditionnelles</span></a>.</p>\n</section>\n<section id=\"subquery-expressions\">\n<h3>Expressions <code class=\"docutils literal notranslate\">Subquery()</code><a class=\"heading-anchor\" href=\"#subquery-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Subquery\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Subquery</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">queryset</em>, <em class=\"sig-param\">output_field<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Subquery\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Il est possible d’ajouter des sous-requêtes explicites à un objet <code class=\"docutils literal notranslate\">QuerySet</code> en utilisant l’expression <code class=\"docutils literal notranslate\">Subquery</code>.</p>\n<p>Par exemple, pour annoter chaque <code class=\"docutils literal notranslate\">post</code> avec l’adresse de courriel de l’auteur du commentaire le plus récent de ce <code class=\"docutils literal notranslate\">post</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> OuterRef<span class=\"p\">,</span> Subquery\n<span class=\"gp\">&gt;&gt;&gt; </span>newest <span class=\"o\">=</span> Comment<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>post<span class=\"o\">=</span>OuterRef<span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s1\">&#39;-created_at&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Post<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>newest_commenter_email<span class=\"o\">=</span>Subquery<span class=\"p\">(</span>newest<span class=\"o\">.</span>values<span class=\"p\">(</span><span class=\"s1\">&#39;email&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">1</span><span class=\"p\">]))</span>\n</code></pre></div>\n<p>Avec PostgreSQL, le code SQL ressemble à ceci :</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</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=\"SQL code\"><code><span class=\"k\">SELECT</span> <span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">,</span> <span class=\"p\">(</span>\n    <span class=\"k\">SELECT</span> U0<span class=\"p\">.</span><span class=\"ss\">&quot;email&quot;</span>\n    <span class=\"k\">FROM</span> <span class=\"ss\">&quot;comment&quot;</span> U0\n    <span class=\"k\">WHERE</span> U0<span class=\"p\">.</span><span class=\"ss\">&quot;post_id&quot;</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">ORDER</span> <span class=\"k\">BY</span> U0<span class=\"p\">.</span><span class=\"ss\">&quot;created_at&quot;</span> <span class=\"k\">DESC</span> <span class=\"k\">LIMIT</span> <span class=\"mi\">1</span>\n<span class=\"p\">)</span> <span class=\"k\">AS</span> <span class=\"ss\">&quot;newest_commenter_email&quot;</span> <span class=\"k\">FROM</span> <span class=\"ss\">&quot;post&quot;</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Les exemples de cette section sont conçus pour montrer comment forcer Django à exécuter une sous-requête. Dans certains cas, il serait possible d’écrire une requête équivalente qui effectue la même tâche plus clairement ou plus efficacement.</p>\n</aside>\n<section id=\"referencing-columns-from-the-outer-queryset\">\n<h4>Référencement des colonnes de la requête parente<a class=\"heading-anchor\" href=\"#referencing-columns-from-the-outer-queryset\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.OuterRef\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">OuterRef</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">field</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.OuterRef\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Utilisez <code class=\"docutils literal notranslate\">OuterRef</code> lorsqu’un jeu de requête dans une <code class=\"docutils literal notranslate\">Subquery</code> a besoin de se référer à un champ de la requête parente. Il se comporte comme une expression <a class=\"reference internal\" href=\"#django.db.models.F\" title=\"django.db.models.F\"><code class=\"xref py py-class docutils literal notranslate\">F</code></a> sauf que le contrôle vérifiant s’il se réfère à un champ valable n’est pas effectué avant que la requête parente ne soit résolue.</p>\n<p>Des instances de <code class=\"docutils literal notranslate\">OuterRef</code> peuvent être utilisées en lien avec des instances imbriquées de <code class=\"docutils literal notranslate\">Subquery</code> pour se référer à un jeu de requête supérieur qui n’est pas le parent immédiat. Par exemple, ce jeu de requête devrait se trouver dans une paire imbriquée d’instances <code class=\"docutils literal notranslate\">Subquery</code> pour être résolu correctement :</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=\"gp\">&gt;&gt;&gt; </span>Book<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>author<span class=\"o\">=</span>OuterRef<span class=\"p\">(</span>OuterRef<span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">)))</span>\n</code></pre></div>\n</section>\n<section id=\"limiting-a-subquery-to-a-single-column\">\n<h4>Limite d’une sous-requête à une seule colonne<a class=\"heading-anchor\" href=\"#limiting-a-subquery-to-a-single-column\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Dans certaines circonstances, une seule colonne doit être renvoyée d’une sous-requête <code class=\"docutils literal notranslate\">Subquery</code>, par exemple quand on veut utiliser la sous-requête comme cible d’une recherche <code class=\"docutils literal notranslate\">__in</code>. Pour renvoyer tous les commentaires de <code class=\"docutils literal notranslate\">posts</code> publiés durant les dernières 24 heures :</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">datetime</span> <span class=\"kn\">import</span> timedelta\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.utils</span> <span class=\"kn\">import</span> timezone\n<span class=\"gp\">&gt;&gt;&gt; </span>one_day_ago <span class=\"o\">=</span> timezone<span class=\"o\">.</span>now<span class=\"p\">()</span> <span class=\"o\">-</span> timedelta<span class=\"p\">(</span>days<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>posts <span class=\"o\">=</span> Post<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>published_at__gte<span class=\"o\">=</span>one_day_ago<span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Comment<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>post__in<span class=\"o\">=</span>Subquery<span class=\"p\">(</span>posts<span class=\"o\">.</span>values<span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">)))</span>\n</code></pre></div>\n<p>Dans ce cas, la sous-requête doit utiliser <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.values\" title=\"django.db.models.query.QuerySet.values\"><code class=\"xref py py-meth docutils literal notranslate\">values()</code></a> pour ne renvoyer qu’une seule colonne : la clé primaire du <code class=\"docutils literal notranslate\">post</code>.</p>\n</section>\n<section id=\"limiting-the-subquery-to-a-single-row\">\n<h4>Limite de la sous-requête à une seule ligne<a class=\"heading-anchor\" href=\"#limiting-the-subquery-to-a-single-row\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Pour empêcher une sous-requête de renvoyer plusieurs lignes, une segmentation (<code class=\"docutils literal notranslate\">[:1]</code>) du résultat de requête est appliquée :</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=\"gp\">&gt;&gt;&gt; </span>subquery <span class=\"o\">=</span> Subquery<span class=\"p\">(</span>newest<span class=\"o\">.</span>values<span class=\"p\">(</span><span class=\"s1\">&#39;email&#39;</span><span class=\"p\">)[:</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Post<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>newest_commenter_email<span class=\"o\">=</span>subquery<span class=\"p\">)</span>\n</code></pre></div>\n<p>Dans ce cas, la sous-requête ne doit renvoyer qu’une seule colonne <em>et</em> une seule ligne : l’adresse électronique du commentaire créé le plus récent.</p>\n<p>(L’utilisation de <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.get\" title=\"django.db.models.query.QuerySet.get\"><code class=\"xref py py-meth docutils literal notranslate\">get()</code></a> à la place d’une segmentation ne fonctionnerait pas car <code class=\"docutils literal notranslate\">OuterRef</code> ne peut pas être résolu tant que le résultat de requête n’est pas utilisé dans une sous-requête <code class=\"docutils literal notranslate\">Subquery</code>.)</p>\n</section>\n<section id=\"exists-subqueries\">\n<h4>Sous-requêtes <code class=\"docutils literal notranslate\">Exists()</code><a class=\"heading-anchor\" href=\"#exists-subqueries\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Exists\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Exists</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">queryset</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Exists\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><code class=\"docutils literal notranslate\">Exists</code> est une sous-classe de <code class=\"docutils literal notranslate\">Subquery</code> utilisant une instruction SQL <code class=\"docutils literal notranslate\">EXISTS</code>. Dans bien des cas, la performance sera meilleure qu’une sous-requête car la base de données est capable de stopper l’évaluation de la sous-requête dès qu’une première ligne correspondante est trouvée.</p>\n<p>Par exemple, pour annoter chaque <code class=\"docutils literal notranslate\">post</code> avec une indication de la présence ou non d’un commentaire durant la journée écoulée :</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Exists<span class=\"p\">,</span> OuterRef\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">datetime</span> <span class=\"kn\">import</span> timedelta\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.utils</span> <span class=\"kn\">import</span> timezone\n<span class=\"gp\">&gt;&gt;&gt; </span>one_day_ago <span class=\"o\">=</span> timezone<span class=\"o\">.</span>now<span class=\"p\">()</span> <span class=\"o\">-</span> timedelta<span class=\"p\">(</span>days<span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>recent_comments <span class=\"o\">=</span> Comment<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    post<span class=\"o\">=</span>OuterRef<span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>    created_at__gte<span class=\"o\">=</span>one_day_ago<span class=\"p\">,</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Post<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>recent_comment<span class=\"o\">=</span>Exists<span class=\"p\">(</span>recent_comments<span class=\"p\">))</span>\n</code></pre></div>\n<p>Avec PostgreSQL, le code SQL ressemble à ceci :</p>\n<div class=\"code-block\" data-language=\"sql\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">SQL</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=\"SQL code\"><code><span class=\"k\">SELECT</span> <span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">,</span> <span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;published_at&quot;</span><span class=\"p\">,</span> <span class=\"k\">EXISTS</span><span class=\"p\">(</span>\n    <span class=\"k\">SELECT</span> U0<span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">,</span> U0<span class=\"p\">.</span><span class=\"ss\">&quot;post_id&quot;</span><span class=\"p\">,</span> U0<span class=\"p\">.</span><span class=\"ss\">&quot;email&quot;</span><span class=\"p\">,</span> U0<span class=\"p\">.</span><span class=\"ss\">&quot;created_at&quot;</span>\n    <span class=\"k\">FROM</span> <span class=\"ss\">&quot;comment&quot;</span> U0\n    <span class=\"k\">WHERE</span> <span class=\"p\">(</span>\n        U0<span class=\"p\">.</span><span class=\"ss\">&quot;created_at&quot;</span> <span class=\"o\">&gt;=</span> YYYY<span class=\"o\">-</span>MM<span class=\"o\">-</span>DD HH<span class=\"p\">:</span>MM<span class=\"p\">:</span>SS <span class=\"k\">AND</span>\n        U0<span class=\"p\">.</span><span class=\"ss\">&quot;post_id&quot;</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"ss\">&quot;post&quot;</span><span class=\"p\">.</span><span class=\"ss\">&quot;id&quot;</span><span class=\"p\">)</span>\n    <span class=\"p\">)</span>\n<span class=\"p\">)</span> <span class=\"k\">AS</span> <span class=\"ss\">&quot;recent_comment&quot;</span> <span class=\"k\">FROM</span> <span class=\"ss\">&quot;post&quot;</span>\n</code></pre></div>\n<p>Il n’est pas nécessaire de forcer <code class=\"docutils literal notranslate\">Exists</code> à se référer à une seule colonne, car les colonnes sont ignorées et un résultat booléen est renvoyé. De même, comme le tri ne joue pas de rôle dans une sous-requête SQL <code class=\"docutils literal notranslate\">EXISTS</code> et ne ferait que baisser la performance, il est automatiquement enlevé.</p>\n<p>Il est possible d’effectuer un <code class=\"docutils literal notranslate\">NOT EXISTS</code> avec <code class=\"docutils literal notranslate\">~Exists()</code>.</p>\n</section>\n<section id=\"filtering-on-a-subquery-expression\">\n<h4>Filtrage sur une expression <code class=\"docutils literal notranslate\">Subquery</code><a class=\"heading-anchor\" href=\"#filtering-on-a-subquery-expression\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Il n’est pas possible de filtrer directement en utilisant <code class=\"docutils literal notranslate\">Subquery</code> et <code class=\"docutils literal notranslate\">Exists</code>, par ex. :</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=\"gp\">&gt;&gt;&gt; </span>Post<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>Exists<span class=\"p\">(</span>recent_comments<span class=\"p\">))</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">TypeError: &#39;Exists&#39; object is not iterable</span>\n</code></pre></div>\n<p>Pour filtrer une expression de sous-requête, vous devez commencer par annoter le jeu de requête, puis filtrer sur la base de cette annotation :</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=\"gp\">&gt;&gt;&gt; </span>Post<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"gp\">... </span>    recent_comment<span class=\"o\">=</span>Exists<span class=\"p\">(</span>recent_comments<span class=\"p\">),</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span><span class=\"o\">.</span>filter<span class=\"p\">(</span>recent_comment<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"using-aggregates-within-a-subquery-expression\">\n<h4>Utilisation d’agrégation dans une expression <code class=\"docutils literal notranslate\">Subquery</code><a class=\"heading-anchor\" href=\"#using-aggregates-within-a-subquery-expression\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Il est possible d’utiliser des agrégats dans une sous-requête, mais cela nécessite une combinaison spécifique de <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">filter()</code></a>, <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.values\" title=\"django.db.models.query.QuerySet.values\"><code class=\"xref py py-meth docutils literal notranslate\">values()</code></a> et <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.annotate\" title=\"django.db.models.query.QuerySet.annotate\"><code class=\"xref py py-meth docutils literal notranslate\">annotate()</code></a> afin d’obtenir un groupement correct dans la sous-requête.</p>\n<p>En supposant que les deux modèles ont un champ <code class=\"docutils literal notranslate\">length</code>, voici comment trouver les <code class=\"docutils literal notranslate\">posts</code> dont la longueur est plus grande que la longueur totale de tous les commentaires ensemble :</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> OuterRef<span class=\"p\">,</span> Subquery<span class=\"p\">,</span> Sum\n<span class=\"gp\">&gt;&gt;&gt; </span>comments <span class=\"o\">=</span> Comment<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>post<span class=\"o\">=</span>OuterRef<span class=\"p\">(</span><span class=\"s1\">&#39;pk&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span>order_by<span class=\"p\">()</span><span class=\"o\">.</span>values<span class=\"p\">(</span><span class=\"s1\">&#39;post&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>total_comments <span class=\"o\">=</span> comments<span class=\"o\">.</span>annotate<span class=\"p\">(</span>total<span class=\"o\">=</span>Sum<span class=\"p\">(</span><span class=\"s1\">&#39;length&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span>values<span class=\"p\">(</span><span class=\"s1\">&#39;total&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Post<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>length__gt<span class=\"o\">=</span>Subquery<span class=\"p\">(</span>total_comments<span class=\"p\">))</span>\n</code></pre></div>\n<p>Le premier <code class=\"docutils literal notranslate\">filter(...)</code> limite la sous-requête aux paramètres qui nous intéressent. <code class=\"docutils literal notranslate\">order_by()</code> enlève le tri <a class=\"reference internal\" href=\"/fr/2.2/ref/models/options/#django.db.models.Options.ordering\" title=\"django.db.models.Options.ordering\"><code class=\"xref py py-attr docutils literal notranslate\">ordering</code></a> par défaut (le cas échéant) du modèle <code class=\"docutils literal notranslate\">Comment</code>, <code class=\"docutils literal notranslate\">values('post')</code> agrège les commentaires par <code class=\"docutils literal notranslate\">Post</code>. Pour terminer, <code class=\"docutils literal notranslate\">annotate(...)</code> effectue l’agrégation. L’ordre dans lequel sont appliqués ces méthodes de requête est important. Dans ce cas, comme la sous-requête doit être limitée à une seule colonne, <code class=\"docutils literal notranslate\">values('total')</code> est obligatoire.</p>\n<p>Il s’agit de la seule manière d’effectuer une agrégation à l’intérieur d’une sous-requête, car <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.aggregate\" title=\"django.db.models.query.QuerySet.aggregate\"><code class=\"xref py py-meth docutils literal notranslate\">aggregate()</code></a> procède à l’évaluation du jeu de requête (et lorsqu’il existe une <code class=\"docutils literal notranslate\">OuterRef</code>, celle-ci ne pourrait pas être résolue).</p>\n</section>\n</section>\n<section id=\"raw-sql-expressions\">\n<h3>Expressions SQL brutes<a class=\"heading-anchor\" href=\"#raw-sql-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.RawSQL\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">RawSQL</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">sql</em>, <em class=\"sig-param\">params</em>, <em class=\"sig-param\">output_field<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.RawSQL\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Parfois, les expressions de base de données ne peuvent pas facilement exprimer une clause <code class=\"docutils literal notranslate\">WHERE</code> complexe. Dans ces cas limites, utilisez l’expression <code class=\"docutils literal notranslate\">RawSQL</code>. 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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models.expressions</span> <span class=\"kn\">import</span> RawSQL\n<span class=\"gp\">&gt;&gt;&gt; </span>queryset<span class=\"o\">.</span>annotate<span class=\"p\">(</span>val<span class=\"o\">=</span>RawSQL<span class=\"p\">(</span><span class=\"s2\">&quot;select col from sometable where othercol = </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span><span class=\"p\">,</span> <span class=\"p\">(</span>someparam<span class=\"p\">,)))</span>\n</code></pre></div>\n<p>Ces expressions brutes ne sont pas toujours portables entre moteurs de base de données (parce que vous écrivez du code SQL explicitement) et elles violent le principe DRY (ne pas se répéter), il s’agit donc de les éviter autant que possible.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Avertissement</p>\n<p>Pour se protéger des <a href=\"#id6\"><span class=\"problematic\" id=\"id7\">`attaques par injection SQL&lt;https://fr.wikipedia.org/wiki/Injection_SQL&gt;`_</span></a>, vous devez échapper tout paramètre pouvant être contrôlé par les utilisateurs en employant <code class=\"docutils literal notranslate\">params</code>. <code class=\"docutils literal notranslate\">params</code> est un paramètre obligatoire pour vous forcer à confirmer que vous n’effectuez pas d’interpolation de code SQL avec des données provenant des utilisateurs.</p>\n<p>Vous devez aussi éviter de placer les substituants entre guillemets dans la chaîne SQL. Cet exemple est vulnérable à l’injection SQL en raison des guillemets autour de <code class=\"docutils literal notranslate\">%s</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>RawSQL<span class=\"p\">(</span><span class=\"s2\">&quot;select col from sometable where othercol = &#39;</span><span class=\"si\">%s</span><span class=\"s2\">&#39;&quot;</span><span class=\"p\">)</span>  <span class=\"c1\"># unsafe!</span>\n</code></pre></div>\n<p>Vous pouvez en apprendre davantage sur le fonctionnement de la <a class=\"reference internal\" href=\"/fr/2.2/topics/security/#sql-injection-protection\"><span class=\"std std-ref\">protection contre les injections SQL</span></a> de Django.</p>\n</aside>\n</section>\n<section id=\"window-functions\">\n<h3>Fonctions de fenêtrage<a class=\"heading-anchor\" href=\"#window-functions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les fonctions de fenêtrage fournissent une méthode pour appliquer des fonctions aux partitions. Au contraire d’une fonction d’agrégat normale qui calcule le résultat final pour chaque ensemble défini par la clause de groupement, les fonctions de fenêtrage opèrent sur des <a class=\"reference internal\" href=\"#window-frames\"><span class=\"std std-ref\">intervalles (frames)</span></a> et des partitions, et calculent le résultat pour chaque ligne.</p>\n<p>Vous pouvez définir plusieurs fenêtres dans la même requête, ce qui dans le contexte de l’ORM Django serait équivalent à inclure plusieurs expressions dans un appel à <a class=\"reference internal\" href=\"/fr/2.2/topics/db/aggregation/\"><span class=\"doc\">QuerySet.annotate()</span></a>. L’ORM n’emploie pas les fenêtres nommées, elles font en fait partie des colonnes sélectionnées.</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.Window\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Window</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">expression</em>, <em class=\"sig-param\">partition_by<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">order_by<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">frame<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">output_field<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.Window\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.Window.filterable\">\n<span class=\"sig-name descname\">filterable</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.Window.filterable\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Vaut <code class=\"docutils literal notranslate\">False</code> par défaut. Le standard SQL interdit le référencement de fonctions de fenêtrage dans la clause <code class=\"docutils literal notranslate\">WHERE</code> et Django génère une exception lors de la construction d’un <code class=\"docutils literal notranslate\">QuerySet</code> qui tenterait de faire cela.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.Window.template\">\n<span class=\"sig-name descname\">template</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.Window.template\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Vaut par défaut  <code class=\"docutils literal notranslate\">%(expression)s OVER %(window)s</code>. Si seul le paramètre <code class=\"docutils literal notranslate\">expression</code> est donné, la clause de fenêtrage sera vide.</p>\n</dd></dl>\n\n</dd></dl>\n\n<p>La classe <code class=\"docutils literal notranslate\">Window</code> est l’expression principale d’une clause <code class=\"docutils literal notranslate\">OVER</code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">expression</code> est soit une <a class=\"reference internal\" href=\"/fr/2.2/ref/models/database-functions/#window-functions\"><span class=\"std std-ref\">fonction de fenêtrage</span></a>, une <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#aggregation-functions\"><span class=\"std std-ref\">fonction d’agrégat</span></a> ou une expression compatible avec une clause de fenêtrage.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">partition_by</code> est une liste d’expressions (les noms de colonnes doivent être enveloppés dans des objets <code class=\"docutils literal notranslate\">F</code>) qui contrôlent le partitionnement des lignes. Le partitionnement limite les lignes utilisées pour calculer le jeu de résultats.</p>\n<p>Le champ <code class=\"docutils literal notranslate\">output_field</code> est défini soit comme paramètre, soit par l’expression.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">order_by</code> accepte une suite d’expressions sur lesquelles vous pouvez appeler <a class=\"reference internal\" href=\"#django.db.models.Expression.asc\" title=\"django.db.models.Expression.asc\"><code class=\"xref py py-meth docutils literal notranslate\">asc()</code></a> et <a class=\"reference internal\" href=\"#django.db.models.Expression.desc\" title=\"django.db.models.Expression.desc\"><code class=\"xref py py-meth docutils literal notranslate\">desc()</code></a>. Ce tri contrôle l’odre dans lequel l’expression est appliquée. Par exemple, si vous faites la somme des lignes dans une partition, le premier résultat est simplement la valeur de la première ligne, le deuxième est la somme des première et deuxième lignes.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\">frame</code> indique quelles autres lignes devraient être utilisées dans le calcul. Voir <a class=\"reference internal\" href=\"#window-frames\"><span class=\"std std-ref\">Portées (frames)</span></a> pour plus de détails.</p>\n<p>Par exemple, pour annoter chaque film avec la note moyenne des films du même studio dans le même genre et la même année</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Avg<span class=\"p\">,</span> F<span class=\"p\">,</span> Window\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models.functions</span> <span class=\"kn\">import</span> ExtractYear\n<span class=\"gp\">&gt;&gt;&gt; </span>Movie<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    avg_rating<span class=\"o\">=</span>Window<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        expression<span class=\"o\">=</span>Avg<span class=\"p\">(</span><span class=\"s1\">&#39;rating&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        partition_by<span class=\"o\">=</span><span class=\"p\">[</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;studio&#39;</span><span class=\"p\">),</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;genre&#39;</span><span class=\"p\">)],</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        order_by<span class=\"o\">=</span>ExtractYear<span class=\"p\">(</span><span class=\"s1\">&#39;released&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span>asc<span class=\"p\">(),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    <span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Cela rend simplement possible la comparaison de la note d’un film par rapport à ses semblables.</p>\n<p>Il peut être intéressant d’appliquer plusieurs expressions sur la même fenêtre, c-à-d sur les mêmes partition et intervalle. Par exemple, l’exemple précédent pourrait être modifié pour inclure également la meilleure et la pire note dans chaque groupe de films (mêmes studio, genre et date de sortie) en utilisant trois fonctions de fenêtrage dans la même requête. La partition et le tri de l’exemple précédent sont extraits dans un dictionnaire pour réduire la répétition</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Avg<span class=\"p\">,</span> F<span class=\"p\">,</span> Max<span class=\"p\">,</span> Min<span class=\"p\">,</span> Window\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models.functions</span> <span class=\"kn\">import</span> ExtractYear\n<span class=\"gp\">&gt;&gt;&gt; </span>window <span class=\"o\">=</span> <span class=\"p\">{</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>   <span class=\"s1\">&#39;partition_by&#39;</span><span class=\"p\">:</span> <span class=\"p\">[</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;studio&#39;</span><span class=\"p\">),</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;genre&#39;</span><span class=\"p\">)],</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>   <span class=\"s1\">&#39;order_by&#39;</span><span class=\"p\">:</span> ExtractYear<span class=\"p\">(</span><span class=\"s1\">&#39;released&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span>asc<span class=\"p\">(),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">}</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>Movie<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    avg_rating<span class=\"o\">=</span>Window<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        expression<span class=\"o\">=</span>Avg<span class=\"p\">(</span><span class=\"s1\">&#39;rating&#39;</span><span class=\"p\">),</span> <span class=\"o\">**</span>window<span class=\"p\">,</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    <span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    best<span class=\"o\">=</span>Window<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        expression<span class=\"o\">=</span>Max<span class=\"p\">(</span><span class=\"s1\">&#39;rating&#39;</span><span class=\"p\">),</span> <span class=\"o\">**</span>window<span class=\"p\">,</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    <span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    worst<span class=\"o\">=</span>Window<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        expression<span class=\"o\">=</span>Min<span class=\"p\">(</span><span class=\"s1\">&#39;rating&#39;</span><span class=\"p\">),</span> <span class=\"o\">**</span>window<span class=\"p\">,</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    <span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Parmi les moteurs de base de données inclus dans Django, MySQL 8.0.2+, PostgreSQL et Oracle prennent en charge les expressions de fenêtrage. La prise en charge des diverses fonctionnalités des expressions de fenêtrage varie en fonction des bases de données. Par exemple, les options dans <a class=\"reference internal\" href=\"#django.db.models.Expression.asc\" title=\"django.db.models.Expression.asc\"><code class=\"xref py py-meth docutils literal notranslate\">asc()</code></a> et <a class=\"reference internal\" href=\"#django.db.models.Expression.desc\" title=\"django.db.models.Expression.desc\"><code class=\"xref py py-meth docutils literal notranslate\">desc()</code></a> ne sont pas toujours prises en charge. Consultez la documentation de votre base de données si nécessaire.</p>\n<section id=\"frames\">\n<span id=\"window-frames\"></span><h4>Portées (frames)<a class=\"heading-anchor\" href=\"#frames\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Pour une portée de fenêtre, vous pouvez choisir soit une suite de lignes basée sur des intervalles, soit une suite de lignes normale.</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.ValueRange\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">ValueRange</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">start<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">end<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.ValueRange\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.ValueRange.frame_type\">\n<span class=\"sig-name descname\">frame_type</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.ValueRange.frame_type\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Cet attribut est défini à <code class=\"docutils literal notranslate\">'RANGE'</code>.</p>\n</dd></dl>\n\n<p>PostgreSQL ne prend en charge <code class=\"docutils literal notranslate\">ValueRange</code> que de manière limitée et ne gère que les points de début et de fin standard, tels que <code class=\"docutils literal notranslate\">CURRENT ROW</code> et <code class=\"docutils literal notranslate\">UNBOUNDED FOLLOWING</code>.</p>\n</dd></dl>\n\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.RowRange\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">RowRange</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">start<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">end<span class=\"o\">=</span><span class=\"default_value\">None</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.RowRange\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.expressions.RowRange.frame_type\">\n<span class=\"sig-name descname\">frame_type</span><a class=\"heading-anchor\" href=\"#django.db.models.expressions.RowRange.frame_type\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Cet attribut est défini à <code class=\"docutils literal notranslate\">'ROWS'</code>.</p>\n</dd></dl>\n\n</dd></dl>\n\n<p>Les deux classes renvoient du SQL selon le gabarit</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=\"p\">(</span>frame_type<span class=\"p\">)</span>s BETWEEN <span class=\"o\">%</span><span class=\"p\">(</span>start<span class=\"p\">)</span>s AND <span class=\"o\">%</span><span class=\"p\">(</span>end<span class=\"p\">)</span>s\n</code></pre></div>\n<p>Les portées réduisent le nombre de lignes utilisées pour calculer le résultat. Elles ciblent un point de départ donné jusqu’à un point d’arrivée. Les portées peuvent être utilisées avec ou sans partition, mais il est généralement utile d’indiquer un tri de la fenêtre pour s’assurer d’un résultat déterministe. Dans une portée, un pair est une ligne de valeur équivalente, ou toutes les lignes si aucune clause de tri n’est présente.</p>\n<p>Le point de départ par défaut d’une portée est <code class=\"docutils literal notranslate\">UNBOUNDED PRECEDING</code> qui correspond à la première ligne de la partition. Le point d’arrivée est toujours explicitement inclus dans le code SQL généré par l’ORM et vaut par défaut <code class=\"docutils literal notranslate\">UNBOUNDED FOLLOWING</code>. La portée par défaut contient toutes les lignes de la partition jusqu’à la dernière ligne du jeu de données.</p>\n<p>Les valeurs acceptées des paramètres <code class=\"docutils literal notranslate\">start</code> et <code class=\"docutils literal notranslate\">end</code> sont <code class=\"docutils literal notranslate\">None</code>, un nombre entier ou zéro. Un nombre négatif pour <code class=\"docutils literal notranslate\">start</code> produit <code class=\"docutils literal notranslate\">N preceding</code>, alors que <code class=\"docutils literal notranslate\">None</code> produit <code class=\"docutils literal notranslate\">UNBOUNDED PRECEDING</code>. Pour <code class=\"docutils literal notranslate\">start</code> comme pour <code class=\"docutils literal notranslate\">end</code>, zéro renvoie <code class=\"docutils literal notranslate\">CURRENT ROW</code>. Des nombres entiers positifs sont acceptés pour <code class=\"docutils literal notranslate\">end</code>.</p>\n<p>Il y a une différence dans ce que <code class=\"docutils literal notranslate\">CURRENT ROW</code> contient. Lorsqu’il est défini en mode <code class=\"docutils literal notranslate\">ROWS</code>, l’intervalle commence et se termine avec la ligne en cours. Lorsqu’il est défini en mode <code class=\"docutils literal notranslate\">RANGE</code>, l’intervalle commence et se termine à la première ou à la dernière ligne du groupe en fonction de la clause de tri. Ainsi, <code class=\"docutils literal notranslate\">RANGE CURRENT ROW</code> évalue l’expression pour les lignes qui ont la même valeur définie par le tri. Comme le gabarit contient à la fois les points <code class=\"docutils literal notranslate\">start</code> et <code class=\"docutils literal notranslate\">end</code>, cela peut être exprimé par</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>ValueRange<span class=\"p\">(</span>start<span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span> end<span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si les « semblables » d’un film sont définis comme les films publiés par le même studio dans le même genre et la même année, cet exemple <code class=\"docutils literal notranslate\">RowRange</code> annote chaque film avec la note moyenne des deux films précédents et des deux films suivants le film concerné</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Avg<span class=\"p\">,</span> F<span class=\"p\">,</span> RowRange<span class=\"p\">,</span> Window\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models.functions</span> <span class=\"kn\">import</span> ExtractYear\n<span class=\"gp\">&gt;&gt;&gt; </span>Movie<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    avg_rating<span class=\"o\">=</span>Window<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        expression<span class=\"o\">=</span>Avg<span class=\"p\">(</span><span class=\"s1\">&#39;rating&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        partition_by<span class=\"o\">=</span><span class=\"p\">[</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;studio&#39;</span><span class=\"p\">),</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;genre&#39;</span><span class=\"p\">)],</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        order_by<span class=\"o\">=</span>ExtractYear<span class=\"p\">(</span><span class=\"s1\">&#39;released&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span>asc<span class=\"p\">(),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        frame<span class=\"o\">=</span>RowRange<span class=\"p\">(</span>start<span class=\"o\">=-</span><span class=\"mi\">2</span><span class=\"p\">,</span> end<span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    <span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Si la base de données le gère, vous pouvez définir les points de départ et de fin sur la base des valeurs d’une expression dans la partition. Si le champ <code class=\"docutils literal notranslate\">released</code> du model <code class=\"docutils literal notranslate\">Movie</code> stocke le mois de publication de chaque film, cet exemple <code class=\"docutils literal notranslate\">ValueRange</code> annote chaque film avec la note moyenne des films semblables publiés entre douze mois avant et douze mois après chaque film.</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Avg<span class=\"p\">,</span> ExpressionList<span class=\"p\">,</span> F<span class=\"p\">,</span> ValueRange<span class=\"p\">,</span> Window\n<span class=\"gp\">&gt;&gt;&gt; </span>Movie<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    avg_rating<span class=\"o\">=</span>Window<span class=\"p\">(</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        expression<span class=\"o\">=</span>Avg<span class=\"p\">(</span><span class=\"s1\">&#39;rating&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        partition_by<span class=\"o\">=</span><span class=\"p\">[</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;studio&#39;</span><span class=\"p\">),</span> F<span class=\"p\">(</span><span class=\"s1\">&#39;genre&#39;</span><span class=\"p\">)],</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        order_by<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;released&#39;</span><span class=\"p\">)</span><span class=\"o\">.</span>asc<span class=\"p\">(),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>        frame<span class=\"o\">=</span>ValueRange<span class=\"p\">(</span>start<span class=\"o\">=-</span><span class=\"mi\">12</span><span class=\"p\">,</span> end<span class=\"o\">=</span><span class=\"mi\">12</span><span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>    <span class=\"p\">),</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n</section>\n<section id=\"technical-information\">\n<h2>Informations techniques<a class=\"heading-anchor\" href=\"#technical-information\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Vous trouverez ci-après des détails d’implémentation technique pouvant être utiles aux auteurs de bibliothèques. L’API technique et les exemples qui suivent aident à créer des expressions de requête génériques pouvant étendre les fonctionnalités intégrées que Django propose.</p>\n<section id=\"expression-api\">\n<h3>API d’expression<a class=\"heading-anchor\" href=\"#expression-api\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les expressions de requête implémentent l”<a class=\"reference internal\" href=\"/fr/2.2/ref/models/lookups/#query-expression\"><span class=\"std std-ref\">API d’expressions de requête</span></a>, mais exposent également un certain nombre de méthodes et d’attributs supplémentaires énumérés ci-dessous. Toutes les expressions de requête doivent hériter de <code class=\"docutils literal notranslate\">Expression()</code> ou d’une sous-classe appropriée.</p>\n<p>Lorsqu’une expression de requête englobe une autre expression, elle est responsable d’appeler les méthodes appropriées de l’expression englobée.</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression\">\n<em class=\"property\"><span class=\"k\">class</span> </em><span class=\"sig-name descname\">Expression</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.contains_aggregate\">\n<span class=\"sig-name descname\">contains_aggregate</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.contains_aggregate\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Indique à Django que cette expression contient une agrégation et qu’une clause <code class=\"docutils literal notranslate\">GROUP BY</code> doit être ajoutée à la requête.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.contains_over_clause\">\n<span class=\"sig-name descname\">contains_over_clause</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.contains_over_clause\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Indique à Django que cette expression contient une expression <a class=\"reference internal\" href=\"#django.db.models.expressions.Window\" title=\"django.db.models.expressions.Window\"><code class=\"xref py py-class docutils literal notranslate\">Window</code></a>. C’est par exemple utilisé pour interdire les expressions de fonction de fenêtrage dans les requêtes qui modifient des données.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.filterable\">\n<span class=\"sig-name descname\">filterable</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.filterable\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Indique à Django que cette expression peut être référencée dans <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.filter\" title=\"django.db.models.query.QuerySet.filter\"><code class=\"xref py py-meth docutils literal notranslate\">QuerySet.filter()</code></a>. Vaut <code class=\"docutils literal notranslate\">True</code> par défaut.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.window_compatible\">\n<span class=\"sig-name descname\">window_compatible</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.window_compatible\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Indique à Django que cette expression peut être utilisée comme expression source dans <a class=\"reference internal\" href=\"#django.db.models.expressions.Window\" title=\"django.db.models.expressions.Window\"><code class=\"xref py py-class docutils literal notranslate\">Window</code></a>. Vaut <code class=\"docutils literal notranslate\">False</code> par défaut.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.resolve_expression\">\n<span class=\"sig-name descname\">resolve_expression</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">query<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">allow_joins<span class=\"o\">=</span><span class=\"default_value\">True</span></em>, <em class=\"sig-param\">reuse<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">summarize<span class=\"o\">=</span><span class=\"default_value\">False</span></em>, <em class=\"sig-param\">for_save<span class=\"o\">=</span><span class=\"default_value\">False</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.resolve_expression\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Offre l’opportunité d’effectuer un éventuel pré-traitement ou validation de l’expression avant que celle-ci ne soit ajoutée à la requête. <code class=\"docutils literal notranslate\">resolve_expression()</code> doit aussi être appelée pour toute expression imbriquée. Une copie <code class=\"docutils literal notranslate\">copy()</code> de <code class=\"docutils literal notranslate\">self</code> devrait être renvoyée avec les éventuelles transformations nécessaires.</p>\n<p><code class=\"docutils literal notranslate\">query</code> est l’implémentation de la requête en fonction du moteur de base de données.</p>\n<p><code class=\"docutils literal notranslate\">allow_joins</code> est une valeur booléenne permettant ou interdisant l’utilisation de jointures dans la requête.</p>\n<p><code class=\"docutils literal notranslate\">reuse</code> est un ensemble de jointures réutilisables dans des scénarios de jointures multiples.</p>\n<p><code class=\"docutils literal notranslate\">summarize</code> est une valeur booléenne qui, quand elle vaut <code class=\"docutils literal notranslate\">True</code>, signale que la requête en cours de calcul est une requête d’agrégation terminale.</p>\n<p><code class=\"docutils literal notranslate\">for_save</code> est une valeur booléenne qui, quand elle vaut <code class=\"docutils literal notranslate\">True</code>, signale que la requête en cours d’exécution effectue une création ou une mise à jour.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.get_source_expressions\">\n<span class=\"sig-name descname\">get_source_expressions</span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.get_source_expressions\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie une liste triée d’expressions internes. 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=\"gp\">&gt;&gt;&gt; </span>Sum<span class=\"p\">(</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;foo&#39;</span><span class=\"p\">))</span><span class=\"o\">.</span>get_source_expressions<span class=\"p\">()</span>\n<span class=\"go\">[F(&#39;foo&#39;)]</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.set_source_expressions\">\n<span class=\"sig-name descname\">set_source_expressions</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">expressions</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.set_source_expressions\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Accepte une liste d’expressions et les stocke afin que <code class=\"docutils literal notranslate\">get_source_expressions()</code> puisse les restituer.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.relabeled_clone\">\n<span class=\"sig-name descname\">relabeled_clone</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">change_map</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.relabeled_clone\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie un clone (copie) de <code class=\"docutils literal notranslate\">self</code>, sachant que tout alias de colonne aura été renommé. Les alias de colonnes sont renommés lorsque des sous-requêtes sont créées. <code class=\"docutils literal notranslate\">relabeled_clone()</code> doit également être appelée pour toute expression imbriquée et attribuée au clone.</p>\n<p><code class=\"docutils literal notranslate\">change_map</code> est un dictionnaire faisant correspondre les anciens alias aux nouveaux.</p>\n<p>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=\"k\">def</span> <span class=\"nf\">relabeled_clone</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> change_map<span class=\"p\">):</span>\n    clone <span class=\"o\">=</span> copy<span class=\"o\">.</span>copy<span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">)</span>\n    clone<span class=\"o\">.</span>expression <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span>expression<span class=\"o\">.</span>relabeled_clone<span class=\"p\">(</span>change_map<span class=\"p\">)</span>\n    <span class=\"k\">return</span> clone\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.convert_value\">\n<span class=\"sig-name descname\">convert_value</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">value</em>, <em class=\"sig-param\">expression</em>, <em class=\"sig-param\">connection</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.convert_value\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un point d’entrée permettant à l’expression de forcer <code class=\"docutils literal notranslate\">value</code> à un type plus approprié.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.get_group_by_cols\">\n<span class=\"sig-name descname\">get_group_by_cols</span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.get_group_by_cols\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Responsable du renvoi de la liste des colonnes référencées par cette expression. <code class=\"docutils literal notranslate\">get_group_by_cols()</code> doit être appelée sur toute expression imbriquée. Les objets <code class=\"docutils literal notranslate\">F()</code> en particulier détiennent une référence sur une colonne.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.asc\">\n<span class=\"sig-name descname\">asc</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">nulls_first<span class=\"o\">=</span><span class=\"default_value\">False</span></em>, <em class=\"sig-param\">nulls_last<span class=\"o\">=</span><span class=\"default_value\">False</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.asc\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie l’expression prête à être triée dans l’ordre croissant.</p>\n<p><code class=\"docutils literal notranslate\">nulls_first</code> et <code class=\"docutils literal notranslate\">nulls_last</code> définissent comment les valeurs nulles sont triées. Voir <a class=\"reference internal\" href=\"#using-f-to-sort-null-values\"><span class=\"std std-ref\">Utilisation de F() pour trier les valeurs nulles</span></a> pour un exemple d’utilisation.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.desc\">\n<span class=\"sig-name descname\">desc</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">nulls_first<span class=\"o\">=</span><span class=\"default_value\">False</span></em>, <em class=\"sig-param\">nulls_last<span class=\"o\">=</span><span class=\"default_value\">False</span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.desc\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie l’expression prête à être triée dans l’ordre décroissant.</p>\n<p><code class=\"docutils literal notranslate\">nulls_first</code> et <code class=\"docutils literal notranslate\">nulls_last</code> définissent comment les valeurs nulles sont triées. Voir <a class=\"reference internal\" href=\"#using-f-to-sort-null-values\"><span class=\"std std-ref\">Utilisation de F() pour trier les valeurs nulles</span></a> pour un exemple d’utilisation.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.models.Expression.reverse_ordering\">\n<span class=\"sig-name descname\">reverse_ordering</span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.reverse_ordering\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie <code class=\"docutils literal notranslate\">self</code> avec toute modification nécessaire pour inverser l’ordre de tri à l’intérieur d’un appel <code class=\"docutils literal notranslate\">order_by</code>. Comme exemple, une expression implémentant <code class=\"docutils literal notranslate\">NULLS LAST</code> changerait sa valeur pour devenir <code class=\"docutils literal notranslate\">NULLS FIRST</code>. Les modifications sont uniquement requises pour les expressions qui implémentent l’ordre de tri telles que <code class=\"docutils literal notranslate\">OrderBy</code>. Cette méthode est appelée lorsque <a class=\"reference internal\" href=\"/fr/2.2/ref/models/querysets/#django.db.models.query.QuerySet.reverse\" title=\"django.db.models.query.QuerySet.reverse\"><code class=\"xref py py-meth docutils literal notranslate\">reverse()</code></a> est appelée sur un jeu de requête (<code class=\"docutils literal notranslate\">QuerySet</code>).</p>\n</dd></dl>\n\n</dd></dl>\n\n</section>\n<section id=\"writing-your-own-query-expressions\">\n<h3>Écriture de ses propres expressions de requête<a class=\"heading-anchor\" href=\"#writing-your-own-query-expressions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Vous pouvez écrire vos propres classes d’expression de requête qui utilisent et peuvent s’intégrer avec d’autres expressions de requête. Prenons un exemple en écrivant une implémentation de la fonction SQL <code class=\"docutils literal notranslate\">COALESCE</code>, sans utiliser les <a class=\"reference internal\" href=\"#func-expressions\"><span class=\"std std-ref\">expressions Func()</span></a> intégrées.</p>\n<p>La fonction SQL <code class=\"docutils literal notranslate\">COALESCE</code> est définie comme acceptant une liste de colonnes ou de valeurs. Elle renvoie la première colonne ou valeur qui n’est pas <code class=\"docutils literal notranslate\">NULL</code>.</p>\n<p>Commençons par définir le gabarit à utiliser pour la génération du SQL ainsi qu’une méthode <code class=\"docutils literal notranslate\">__init__()</code> pour définir quelques attributs :</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\">copy</span>\n<span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> Expression\n\n<span class=\"k\">class</span> <span class=\"nc\">Coalesce</span><span class=\"p\">(</span>Expression<span class=\"p\">):</span>\n    template <span class=\"o\">=</span> <span class=\"s1\">&#39;COALESCE( </span><span class=\"si\">%(expressions)s</span><span class=\"s1\"> )&#39;</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> expressions<span class=\"p\">,</span> output_field<span class=\"p\">):</span>\n      <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span>output_field<span class=\"o\">=</span>output_field<span class=\"p\">)</span>\n      <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span>expressions<span class=\"p\">)</span> <span class=\"o\">&lt;</span> <span class=\"mi\">2</span><span class=\"p\">:</span>\n          <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;expressions must have at least 2 elements&#39;</span><span class=\"p\">)</span>\n      <span class=\"k\">for</span> expression <span class=\"ow\">in</span> expressions<span class=\"p\">:</span>\n          <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"nb\">hasattr</span><span class=\"p\">(</span>expression<span class=\"p\">,</span> <span class=\"s1\">&#39;resolve_expression&#39;</span><span class=\"p\">):</span>\n              <span class=\"k\">raise</span> <span class=\"ne\">TypeError</span><span class=\"p\">(</span><span class=\"s1\">&#39;</span><span class=\"si\">%r</span><span class=\"s1\"> is not an Expression&#39;</span> <span class=\"o\">%</span> expression<span class=\"p\">)</span>\n      <span class=\"bp\">self</span><span class=\"o\">.</span>expressions <span class=\"o\">=</span> expressions\n</code></pre></div>\n<p>Nous effectuons quelques validations de base sur les paramètres, y compris le minimum de 2 colonnes ou valeurs, et nous nous assurons qu’il s’agisse bien d’expressions. <code class=\"docutils literal notranslate\">output_field</code> est ici obligatoire afin que Django sache à quel type de champ de modèle attribuer l’éventuel résultat.</p>\n<p>Nous implémentons maintenant le prétraitement et la validation. Comme nous n’avons aucune validation propre à ce stade, nous ne faisons que la déléguer aux expressions imbriquées :</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\">def</span> <span class=\"nf\">resolve_expression</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> query<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> allow_joins<span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> reuse<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> summarize<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">,</span> for_save<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span>\n    c <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span>copy<span class=\"p\">()</span>\n    c<span class=\"o\">.</span>is_summary <span class=\"o\">=</span> summarize\n    <span class=\"k\">for</span> pos<span class=\"p\">,</span> expression <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span>expressions<span class=\"p\">):</span>\n        c<span class=\"o\">.</span>expressions<span class=\"p\">[</span>pos<span class=\"p\">]</span> <span class=\"o\">=</span> expression<span class=\"o\">.</span>resolve_expression<span class=\"p\">(</span>query<span class=\"p\">,</span> allow_joins<span class=\"p\">,</span> reuse<span class=\"p\">,</span> summarize<span class=\"p\">,</span> for_save<span class=\"p\">)</span>\n    <span class=\"k\">return</span> c\n</code></pre></div>\n<p>Ensuite, nous écrivons la méthode responsable de la génération du code SQL :</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\">def</span> <span class=\"nf\">as_sql</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> compiler<span class=\"p\">,</span> connection<span class=\"p\">,</span> template<span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    sql_expressions<span class=\"p\">,</span> sql_params <span class=\"o\">=</span> <span class=\"p\">[],</span> <span class=\"p\">[]</span>\n    <span class=\"k\">for</span> expression <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span>expressions<span class=\"p\">:</span>\n        sql<span class=\"p\">,</span> params <span class=\"o\">=</span> compiler<span class=\"o\">.</span>compile<span class=\"p\">(</span>expression<span class=\"p\">)</span>\n        sql_expressions<span class=\"o\">.</span>append<span class=\"p\">(</span>sql<span class=\"p\">)</span>\n        sql_params<span class=\"o\">.</span>extend<span class=\"p\">(</span>params<span class=\"p\">)</span>\n    template <span class=\"o\">=</span> template <span class=\"ow\">or</span> <span class=\"bp\">self</span><span class=\"o\">.</span>template\n    data <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;expressions&#39;</span><span class=\"p\">:</span> <span class=\"s1\">&#39;,&#39;</span><span class=\"o\">.</span>join<span class=\"p\">(</span>sql_expressions<span class=\"p\">)}</span>\n    <span class=\"k\">return</span> template <span class=\"o\">%</span> data<span class=\"p\">,</span> params\n\n<span class=\"k\">def</span> <span class=\"nf\">as_oracle</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> compiler<span class=\"p\">,</span> connection<span class=\"p\">):</span>\n    <span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Example of vendor specific handling (Oracle in this case).</span>\n<span class=\"sd\">    Let&#39;s make the function name lowercase.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n    <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>as_sql<span class=\"p\">(</span>compiler<span class=\"p\">,</span> connection<span class=\"p\">,</span> template<span class=\"o\">=</span><span class=\"s1\">&#39;coalesce( </span><span class=\"si\">%(expressions)s</span><span class=\"s1\"> )&#39;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Les méthodes <code class=\"docutils literal notranslate\">as_sql()</code> savent gérer des paramètres nommés personnalisés, permettantaux méthodes <code class=\"docutils literal notranslate\">as_nomfournisseur()</code> de remplacer des données utilisées pour générer la chaîne SQL. Il est préférable d’utiliser des paramètres nommés pour <code class=\"docutils literal notranslate\">as_sql()</code> pour la personnalisation que de transformer <code class=\"docutils literal notranslate\">self</code> dans les méthodes <code class=\"docutils literal notranslate\">as_nomfournisseur()</code> car cela peut produire des erreurs lors du fonctionnement sur d’autres moteurs de base de données. Si votre classe s’appuie sur des attributs de classe pour définir des données, considérez la possibilité de permettre des surcharges dans votre méthode <code class=\"docutils literal notranslate\">as_sql()</code>.</p>\n<p>Nous générons le code SQL pour chacune des <code class=\"docutils literal notranslate\">expressions</code> en utilisant la méthode <code class=\"docutils literal notranslate\">compiler.compile()</code> et en combinant les résultats avec des virgules. Puis le gabarit est complété avec nos données et le code SQL est renvoyé avec ses paramètres.</p>\n<p>Nous avons également défini une implémentation personnalisée spécifique au moteur Oracle. La fonction <code class=\"docutils literal notranslate\">as_oracle()</code> sera appelée à la place de <code class=\"docutils literal notranslate\">as_sql()</code> quand le moteur Oracle est en fonction.</p>\n<p>Finalement, nous implémentons les autres méthodes qui permettent à notre expression de requête de collaborer harmonieusement avec d’autres expressions de requête :</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\">def</span> <span class=\"nf\">get_source_expressions</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>expressions\n\n<span class=\"k\">def</span> <span class=\"nf\">set_source_expressions</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> expressions<span class=\"p\">):</span>\n    <span class=\"bp\">self</span><span class=\"o\">.</span>expressions <span class=\"o\">=</span> expressions\n</code></pre></div>\n<p>Voyons comment cela fonctionne :</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=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> F<span class=\"p\">,</span> Value<span class=\"p\">,</span> CharField\n<span class=\"gp\">&gt;&gt;&gt; </span>qs <span class=\"o\">=</span> Company<span class=\"o\">.</span>objects<span class=\"o\">.</span>annotate<span class=\"p\">(</span>\n<span class=\"gp\">... </span>   tagline<span class=\"o\">=</span>Coalesce<span class=\"p\">([</span>\n<span class=\"gp\">... </span>       F<span class=\"p\">(</span><span class=\"s1\">&#39;motto&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>       F<span class=\"p\">(</span><span class=\"s1\">&#39;ticker_name&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>       F<span class=\"p\">(</span><span class=\"s1\">&#39;description&#39;</span><span class=\"p\">),</span>\n<span class=\"gp\">... </span>       Value<span class=\"p\">(</span><span class=\"s1\">&#39;No Tagline&#39;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span>       <span class=\"p\">],</span> output_field<span class=\"o\">=</span>CharField<span class=\"p\">()))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">for</span> c <span class=\"ow\">in</span> qs<span class=\"p\">:</span>\n<span class=\"gp\">... </span>    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;</span><span class=\"si\">%s</span><span class=\"s2\">: </span><span class=\"si\">%s</span><span class=\"s2\">&quot;</span> <span class=\"o\">%</span> <span class=\"p\">(</span>c<span class=\"o\">.</span>name<span class=\"p\">,</span> c<span class=\"o\">.</span>tagline<span class=\"p\">))</span>\n<span class=\"gp\">...</span>\n<span class=\"go\">Google: Do No Evil</span>\n<span class=\"go\">Apple: AAPL</span>\n<span class=\"go\">Yahoo: Internet Company</span>\n<span class=\"go\">Django Software Foundation: No Tagline</span>\n</code></pre></div>\n<section id=\"avoiding-sql-injection\">\n<span id=\"avoiding-sql-injection-in-query-expressions\"></span><h4>Empêchement des injections SQL<a class=\"heading-anchor\" href=\"#avoiding-sql-injection\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Comme les paramètres nommés d’une fonction <code class=\"docutils literal notranslate\">Func</code> pour <code class=\"docutils literal notranslate\">__init__()</code> (<code class=\"docutils literal notranslate\">**extra</code>) et <code class=\"docutils literal notranslate\">as_sql()</code> (<code class=\"docutils literal notranslate\">**extra_context</code>) sont interpolés pour former une chaîne SQL et non pas transmis comme paramètres de requête (où le pilote de base de données se serait chargé de les échapper), ils ne doivent pas contenir des données non sûres soumises par des utilisateurs.</p>\n<p>Par exemple, si le contenu de <code class=\"docutils literal notranslate\">substring</code> provient d’un utilisateur, cette fonction est vulnérable à l’injection SQL</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.db.models</span> <span class=\"kn\">import</span> Func\n\n<span class=\"k\">class</span> <span class=\"nc\">Position</span><span class=\"p\">(</span>Func<span class=\"p\">):</span>\n    function <span class=\"o\">=</span> <span class=\"s1\">&#39;POSITION&#39;</span>\n    template <span class=\"o\">=</span> <span class=\"s2\">&quot;</span><span class=\"si\">%(function)s</span><span class=\"s2\">(&#39;</span><span class=\"si\">%(substring)s</span><span class=\"s2\">&#39; in </span><span class=\"si\">%(expressions)s</span><span class=\"s2\">)&quot;</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> expression<span class=\"p\">,</span> substring<span class=\"p\">):</span>\n        <span class=\"c1\"># substring=substring is a SQL injection vulnerability!</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span>expression<span class=\"p\">,</span> substring<span class=\"o\">=</span>substring<span class=\"p\">)</span>\n</code></pre></div>\n<p>Cette fonction produit une chaîne SQL sans paramètre. Comme <code class=\"docutils literal notranslate\">substring</code> est transmis à <code class=\"docutils literal notranslate\">super().__init__()</code> comme paramètre nommé, il est interpolé dans la chaîne SQL avant que la requête soit envoyée à la base de données.</p>\n<p>Voici une réécriture corrigée</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\">Position</span><span class=\"p\">(</span>Func<span class=\"p\">):</span>\n    function <span class=\"o\">=</span> <span class=\"s1\">&#39;POSITION&#39;</span>\n    arg_joiner <span class=\"o\">=</span> <span class=\"s1\">&#39; IN &#39;</span>\n\n    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> expression<span class=\"p\">,</span> substring<span class=\"p\">):</span>\n        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span>substring<span class=\"p\">,</span> expression<span class=\"p\">)</span>\n</code></pre></div>\n<p>Quand <code class=\"docutils literal notranslate\">substring</code> est transmis sous forme de paramètre positionnel, il est ensuite transmis comme paramètre à la requête de base de données.</p>\n</section>\n</section>\n<section id=\"adding-support-in-third-party-database-backends\">\n<h3>Ajout de la prise en charge de moteurs de base de données externes<a class=\"heading-anchor\" href=\"#adding-support-in-third-party-database-backends\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous utilisez un moteur de base de données qui utilise une syntaxe SQL différente pour certaines fonctions, vous pouvez ajouter sa prise en charge en greffant une nouvelle méthode dans la classe de la fonction.</p>\n<p>Admettons que nous écrivons un moteur pour SQL Server de Microsoft qui utilise l’instruction SQL <code class=\"docutils literal notranslate\">LEN</code> au lieu de <code class=\"docutils literal notranslate\">LENGTH</code> pour la fonction <a class=\"reference internal\" href=\"/fr/2.2/ref/models/database-functions/#django.db.models.functions.Length\" title=\"django.db.models.functions.Length\"><code class=\"xref py py-class docutils literal notranslate\">Length</code></a>. Nous allons greffer une nouvelle méthode appelée <code class=\"docutils literal notranslate\">as_sqlserver()</code> dans la classe <code class=\"docutils literal notranslate\">Length</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\">from</span> <span class=\"nn\">django.db.models.functions</span> <span class=\"kn\">import</span> Length\n\n<span class=\"k\">def</span> <span class=\"nf\">sqlserver_length</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> compiler<span class=\"p\">,</span> connection<span class=\"p\">):</span>\n    <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span>as_sql<span class=\"p\">(</span>compiler<span class=\"p\">,</span> connection<span class=\"p\">,</span> function<span class=\"o\">=</span><span class=\"s1\">&#39;LEN&#39;</span><span class=\"p\">)</span>\n\nLength<span class=\"o\">.</span>as_sqlserver <span class=\"o\">=</span> sqlserver_length\n</code></pre></div>\n<p>Il est aussi possible de personnaliser le code SQL en utilisant le paramètre <code class=\"docutils literal notranslate\">template</code> de <code class=\"docutils literal notranslate\">as_sql()</code>.</p>\n<p>Nous utilisons <code class=\"docutils literal notranslate\">as_sqlserver()</code> parce que <code class=\"docutils literal notranslate\">django.db.connection.vendor</code> renvoie <code class=\"docutils literal notranslate\">sqlserver</code> comme moteur.</p>\n<p>Les moteurs tiers peuvent inscrire leurs fonctions dans le fichier <code class=\"docutils literal notranslate\">__init__.py</code> de premier niveau du paquet de moteur ou dans un fichier (ou paquet) <code class=\"docutils literal notranslate\">expressions.py</code> de premier niveauqui est lui-même importé depuis <code class=\"docutils literal notranslate\">__init__.py</code>.</p>\n<p>Pour les projets d’utilisateurs qui souhaitent adapter le moteur qu’ils utilisent, ce code devrait se trouver dans une méthode <a class=\"reference internal\" href=\"/fr/2.2/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\">AppConfig.ready()</code></a>.</p>\n</section>\n</section>","rootId":"query-expressions","toc":[{"title":"Arithmétique prise en charge","anchor":"supported-arithmetic","children":[]},{"title":"Quelques exemples","anchor":"some-examples","children":[]},{"title":"Expressions intégrées","anchor":"built-in-expressions","children":[{"title":"Expressions F()","anchor":"f-expressions","children":[{"title":"Prévention des conflits de concurrence avec F()","anchor":"avoiding-race-conditions-using-f","children":[]},{"title":"Les attributions par F() persistent après Model.save()","anchor":"f-assignments-persist-after-model-save","children":[]},{"title":"Utilisation de F() dans les filtres","anchor":"using-f-in-filters","children":[]},{"title":"Utilisation de F() avec les annotations","anchor":"using-f-with-annotations","children":[]},{"title":"Utilisation de F() pour trier les valeurs nulles","anchor":"using-f-to-sort-null-values","children":[]}]},{"title":"Expressions Func()","anchor":"func-expressions","children":[]},{"title":"Expressions Aggregate()","anchor":"aggregate-expressions","children":[]},{"title":"Création de ses propres fonctions d’agrégation","anchor":"creating-your-own-aggregate-functions","children":[]},{"title":"Expressions Value()","anchor":"value-expressions","children":[]},{"title":"Expressions ExpressionWrapper()","anchor":"expressionwrapper-expressions","children":[]},{"title":"Expressions conditionnelles","anchor":"conditional-expressions","children":[]},{"title":"Expressions Subquery()","anchor":"subquery-expressions","children":[{"title":"Référencement des colonnes de la requête parente","anchor":"referencing-columns-from-the-outer-queryset","children":[]},{"title":"Limite d’une sous-requête à une seule colonne","anchor":"limiting-a-subquery-to-a-single-column","children":[]},{"title":"Limite de la sous-requête à une seule ligne","anchor":"limiting-the-subquery-to-a-single-row","children":[]},{"title":"Sous-requêtes Exists()","anchor":"exists-subqueries","children":[]},{"title":"Filtrage sur une expression Subquery","anchor":"filtering-on-a-subquery-expression","children":[]},{"title":"Utilisation d’agrégation dans une expression Subquery","anchor":"using-aggregates-within-a-subquery-expression","children":[]}]},{"title":"Expressions SQL brutes","anchor":"raw-sql-expressions","children":[]},{"title":"Fonctions de fenêtrage","anchor":"window-functions","children":[{"title":"Portées (frames)","anchor":"frames","children":[]}]}]},{"title":"Informations techniques","anchor":"technical-information","children":[{"title":"API d’expression","anchor":"expression-api","children":[]},{"title":"Écriture de ses propres expressions de requête","anchor":"writing-your-own-query-expressions","children":[{"title":"Empêchement des injections SQL","anchor":"avoiding-sql-injection","children":[]}]},{"title":"Ajout de la prise en charge de moteurs de base de données externes","anchor":"adding-support-in-third-party-database-backends","children":[]}]}],"breadcrumbs":[{"docname":"ref/index","title":"Référence de l’API","url":"/fr/2.2/ref/"},{"docname":"ref/models/index","title":"Modèles","url":"/fr/2.2/ref/models/"}],"prev":{"docname":"ref/models/lookups","title":"API de référence des expressions de recherche","url":"/fr/2.2/ref/models/lookups/"},"next":{"docname":"ref/models/conditional-expressions","title":"Expressions conditionnelles","url":"/fr/2.2/ref/models/conditional-expressions/"},"formats":{"html":"/fr/2.2/ref/models/expressions/","markdown":"/fr/2.2/ref/models/expressions.md","json":"/fr/2.2/ref/models/expressions.json"},"source":"https://github.com/django/django/blob/stable/2.2.x/docs/ref/models/expressions.txt","official":"https://docs.djangoproject.com/fr/2.2/ref/models/expressions/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}