{"title":"Expressions de requête","version":"1.9","locale":"fr","docname":"ref/models/expressions","url":"/fr/1.9/ref/models/expressions/","canonical":"https://djangodocs.dev/fr/1.9/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<aside class=\"version-note version-changed\" data-version=\"1.9\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 1.9</p><p>La prise en charge des expressions au moment de la création de nouvelles instances de modèles a été ajoutée.</p>\n</aside>\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 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</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<aside class=\"version-note version-changed\" data-version=\"1.8\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 1.8</p><p>Certains de ces exemples se basent sur des fonctionnalités nouvelles dans Django 1.8.</p>\n</aside>\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> F<span class=\"p\">,</span> Count<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()</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</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/1.9/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>Instead, Django uses the <code class=\"docutils literal notranslate\">F()</code> object to generate an SQL expression that\ndescribes the required operation at the database level.</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<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Afin de pouvoir accéder à la nouvelle valeur qui a été enregistrée de cette manière, l’objet a besoin d’ê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</aside>\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/1.9/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/1.9/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/1.9/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><code class=\"docutils literal notranslate\">F()</code> assignments persist after <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><code class=\"docutils literal notranslate\">F()</code> objects assigned to model fields persist after saving the model\ninstance and will be applied on each <a class=\"reference internal\" href=\"/fr/1.9/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>. For example:</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> will be updated twice in this case. If it’s initially <code class=\"docutils literal notranslate\">1</code>,\nthe final value will be <code class=\"docutils literal notranslate\">3</code>.</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/1.9/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</section>\n</section>\n<section id=\"func-expressions\">\n<span id=\"id3\"></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<aside class=\"version-note version-added\" data-version=\"1.8\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.8</p></aside>\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> Func<span class=\"p\">,</span> F\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/1.9/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</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</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>. Notez que les mots-clés <code class=\"docutils literal notranslate\">function</code> et <code class=\"docutils literal notranslate\">template</code> peuvent être utilisés pour remplacer respectivement les attributs <code class=\"docutils literal notranslate\">function</code> et <code class=\"docutils literal notranslate\">template</code>, 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/1.9/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\">expression</em>, <em class=\"sig-param\">output_field<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(%(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</dd></dl>\n\n<p>Le paramètre <code class=\"docutils literal notranslate\">expression</code> peut être le nom d’un champ de modèle ou une autre expression. Il sera converti 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<aside class=\"version-note version-changed\" data-version=\"1.8\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 1.8</p><p><code class=\"docutils literal notranslate\">output_field</code> est un nouveau paramètre.</p>\n</aside>\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=\"1.8\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.8</p><p>Les fonctions d’agrégation sont dorénavant capables de contenir de l’arithmétique et de référencer plusieurs champs de modèle dans une seule fonction.</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\">Count</span><span class=\"p\">(</span>Aggregate<span class=\"p\">):</span>\n    <span class=\"c1\"># supports COUNT(distinct field)</span>\n    function <span class=\"o\">=</span> <span class=\"s1\">&#39;COUNT&#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\">%(distinct)s%(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> expression<span class=\"p\">,</span> distinct<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>Count<span class=\"p\">,</span> <span class=\"bp\">self</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            distinct<span class=\"o\">=</span><span class=\"s1\">&#39;DISTINCT &#39;</span> <span class=\"k\">if</span> distinct <span class=\"k\">else</span> <span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n            output_field<span class=\"o\">=</span>IntegerField<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<aside class=\"version-note version-added\" data-version=\"1.8\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.8</p></aside>\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<aside class=\"version-note version-added\" data-version=\"1.8\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.8</p></aside>\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/1.9/ref/models/conditional-expressions/\"><span class=\"doc\">Expressions conditionnelles</span></a>.</p>\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<aside class=\"version-note version-added\" data-version=\"1.8\" role=\"note\">\n<p class=\"version-note-title\">New in Django 1.8</p></aside>\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>You should be very careful to escape any parameters that the user can\ncontrol by using <code class=\"docutils literal notranslate\">params</code> in order to protect against <a class=\"reference internal\" href=\"/fr/1.9/topics/security/#sql-injection-protection\"><span class=\"std std-ref\">SQL injection\nattacks</span></a>. <code class=\"docutils literal notranslate\">params</code> is a required argument to\nforce you to acknowledge that you’re not interpolating your SQL with user\nprovided data.</p>\n</aside>\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/1.9/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 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</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\">self</em>, <em class=\"sig-param\">value</em>, <em class=\"sig-param\">expression</em>, <em class=\"sig-param\">connection</em>, <em class=\"sig-param\">context</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.refs_aggregate\">\n<span class=\"sig-name descname\">refs_aggregate</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">existing_aggregates</em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.models.Expression.refs_aggregate\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie un tuple contenant les valeurs <code class=\"docutils literal notranslate\">(agrégation, chemin_recherche)</code> de la première agrégation que cette expression (ou d’éventuelles expressions imbriquées) référence, ou <code class=\"docutils literal notranslate\">(False, ())</code> si aucune agrégation n’est référencée. 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>queryset<span class=\"o\">.</span>filter<span class=\"p\">(</span>num_chairs__gt<span class=\"o\">=</span>F<span class=\"p\">(</span><span class=\"s1\">&#39;sum__employees&#39;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>L’expression <code class=\"docutils literal notranslate\">F()</code> référence ici un calcul <code class=\"docutils literal notranslate\">Sum()</code> précédent, ce qui signifie que cette expression de filtre doit être ajoutée à la clause <code class=\"docutils literal notranslate\">HAVING</code> plutôt qu’à la clause <code class=\"docutils literal notranslate\">WHERE</code>.</p>\n<p>Dans la majorité des cas, le renvoi du résultat de <code class=\"docutils literal notranslate\">refs_aggregate</code> de n’importe quelle expression imbriquée devrait être approprié, car les expressions intégrées nécessaires vont renvoyer les valeurs correctes.</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><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</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><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</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/1.9/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> <span class=\"o\">**</span>extra<span class=\"p\">):</span>\n      <span class=\"nb\">super</span><span class=\"p\">(</span>Coalesce<span class=\"p\">,</span> <span class=\"bp\">self</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      <span class=\"bp\">self</span><span class=\"o\">.</span>extra <span class=\"o\">=</span> extra\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>\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    <span class=\"bp\">self</span><span class=\"o\">.</span>extra<span class=\"p\">[</span><span class=\"s1\">&#39;expressions&#39;</span><span class=\"p\">]</span> <span class=\"o\">=</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> <span class=\"bp\">self</span><span class=\"o\">.</span>template <span class=\"o\">%</span> <span class=\"bp\">self</span><span class=\"o\">.</span>extra<span class=\"p\">,</span> sql_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=\"bp\">self</span><span class=\"o\">.</span>template <span class=\"o\">=</span> <span class=\"s1\">&#39;coalesce( </span><span class=\"si\">%(expressions)s</span><span class=\"s1\"> )&#39;</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>\n</code></pre></div>\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>\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/1.9/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/1.9/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":"F() assignments persist after 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":"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 SQL brutes","anchor":"raw-sql-expressions","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":"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/1.9/ref/"},{"docname":"ref/models/index","title":"Modèles","url":"/fr/1.9/ref/models/"}],"prev":{"docname":"ref/models/lookups","title":"API de référence des expressions de recherche","url":"/fr/1.9/ref/models/lookups/"},"next":{"docname":"ref/models/conditional-expressions","title":"Expressions conditionnelles","url":"/fr/1.9/ref/models/conditional-expressions/"},"formats":{"html":"/fr/1.9/ref/models/expressions/","markdown":"/fr/1.9/ref/models/expressions.md","json":"/fr/1.9/ref/models/expressions.json"},"source":"https://github.com/django/django/blob/stable/1.9.x/docs/ref/models/expressions.txt","official":"https://docs.djangoproject.com/fr/1.9/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","fr","ja","id","pt-br","es"]}