{"title":"Personnalisation de l’authentification dans Django","version":"5.1","locale":"fr","docname":"topics/auth/customizing","url":"/fr/5.1/topics/auth/customizing/","canonical":"https://djangodocs.dev/fr/5.1/topics/auth/customizing/","summary":"L’authentification livrée avec Django est suffisante dans la plupart des cas, mais vous pouvez rencontrez des besoins qui ne sont pas couverts par la solution…","html":"<h1>Personnalisation de l’authentification dans Django<a class=\"heading-anchor\" href=\"#customizing-authentication-in-django\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>L’authentification livrée avec Django est suffisante dans la plupart des cas, mais vous pouvez rencontrez des besoins qui ne sont pas couverts par la solution proposée par défaut. Afin de personnaliser l’authentification pour les besoins de vos projets, vous devez comprendre quels sont les points d’ancrage permettant d’étendre et de remplacer les composants du système de Django. Ce document fournit des détails sur la façon dont le système d’authentification peut être adapté.</p>\n<p>Les <a class=\"reference internal\" href=\"#authentication-backends\"><span class=\"std std-ref\">moteurs d’authentification</span></a> permettent d’adapter le système lorsque un nom d’utilisateur et un mot de passe stockés dans le modèle d’utilisateur doivent servir à authentifier l’utilisateur avec un autre service que celui par défaut de Django.</p>\n<p>Vous pouvez donner des <a class=\"reference internal\" href=\"#custom-permissions\"><span class=\"std std-ref\">permissions personnalisées</span></a> à vos modèles qui peuvent être vérifiées à travers le système d’autorisation de Django.</p>\n<p>Vous pouvez <a class=\"reference internal\" href=\"#extending-user\"><span class=\"std std-ref\">étendre</span></a> le modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> par défaut ou le <a class=\"reference internal\" href=\"#auth-custom-user\"><span class=\"std std-ref\">substituer</span></a> par un tout autre modèle personnalisé.</p>\n<section id=\"other-authentication-sources\">\n<span id=\"authentication-backends\"></span><h2>Autres sources d’authentification<a class=\"heading-anchor\" href=\"#other-authentication-sources\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Dans certaines situations, il peut être nécessaire de se connecter à une autre source d’authentification, c’est-à-dire une autre source de noms d’utilisateur et de mots de passe ou d’autres méthodes d’authentification.</p>\n<p>Par exemple, votre entreprise possède peut-être déjà une infrastructure LDAP stockant les noms d’utilisateur et mots de passe pour tous ses employés. Il serait fastidieux aussi bien pour l’administrateur réseau que pour les utilisateurs eux-mêmes de devoir gérer des comptes séparés dans LDAP et dans les applications basées sur Django.</p>\n<p>Ainsi, pour faire face à ce genre de situations, le système d’authentification de Django vous permet de brancher d’autres sources d’authentification. Vous pouvez surcharger le système par défaut de Django basé sur la base de données ou vous pouvez utiliser le système par défaut en parallèle avec d’autres systèmes.</p>\n<p>Consultez la <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#authentication-backends-reference\"><span class=\"std std-ref\">référence sur les moteurs d’authentification</span></a> pour plus d’informations sur les moteurs d’authentification intégrés à Django.</p>\n<section id=\"specifying-authentication-backends\">\n<h3>Définition de moteurs d’authentification<a class=\"heading-anchor\" href=\"#specifying-authentication-backends\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>En arrière-plan, Django maintient une liste de « moteurs d’authentification » qu’il sollicite lors de l’authentification. Lorsque quelqu’un appelle <a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.authenticate\" title=\"django.contrib.auth.authenticate\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.authenticate()</span></code></a> comme expliqué ci-dessus dans <a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#how-to-log-a-user-in\"><span class=\"std std-ref\">Comment connecter un utilisateur</span></a>, Django tente une authentification avec chaque moteur d’authentification. Si la première méthode d’authentification échoue, Django essaie avec la deuxième et ainsi de suite jusqu’à ce que tous les moteurs aient été sollicités.</p>\n<p>La liste des moteurs d’authentification à utiliser est définie dans le réglage <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTHENTICATION_BACKENDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTHENTICATION_BACKENDS</span></code></a>. Il doit s’agir d’une liste de chemins Python vers des classes Python qui sont capables d’authentifier des utilisateurs. Ces classes peuvent se trouver n’importe où dans votre chemin Python.</p>\n<p>Par défaut, <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTHENTICATION_BACKENDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTHENTICATION_BACKENDS</span></code></a> contient :</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=\"p\">[</span><span class=\"s2\">&quot;django.contrib.auth.backends.ModelBackend&quot;</span><span class=\"p\">]</span>\n</code></pre></div>\n<p>Il s’agit du moteur d’authentification de base qui vérifie la base de données Django des utilisateurs et interroge les permissions intégrées. Il ne protège pas contre les attaques de force brute et n’utilise pas de mécanisme de « rate limiting » (restriction du nombre de tentatives dans le temps). Vous pouvez soit écrire votre propre mécanisme de restriction dans un moteur d’authentification personnalisé ou utiliser les mécanismes offerts par la plupart des serveurs Web.</p>\n<p>L’ordre dans la liste <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTHENTICATION_BACKENDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTHENTICATION_BACKENDS</span></code></a> a son importance ; si le même nom d’utilisateur et mot de passe est valable dans plusieurs moteurs, Django s’arrête dès qu’un moteur a accepté les données d’authentification.</p>\n<p>Si un moteur génère une exception <a class=\"reference internal\" href=\"/fr/5.1/ref/exceptions/#django.core.exceptions.PermissionDenied\" title=\"django.core.exceptions.PermissionDenied\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">PermissionDenied</span></code></a>, l’authentification échouera immédiatement. Django ne continue pas avec les moteurs suivants.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Dès qu’un utilisateur s’est authentifié, Django mémorise le moteur utilisé pour authentifier cet utilisateur dans sa session ; il réutilise ensuite ce même moteur pour toute la durée de la session chaque fois qu’il est nécessaire d’accéder à l’utilisateur actuellement authentifié. Cela signifie en pratique que les sources d’authentification sont mises en cache par session et que si vous modifiez <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTHENTICATION_BACKENDS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTHENTICATION_BACKENDS</span></code></a>, vous devrez réinitialiser les données de sessions dans le cas où vous voulez forcer les utilisateurs à s’authentifier à nouveau en utilisant une autre méthode. Une façon simple de faire cela est d’exécuter <code class=\"docutils literal notranslate\"><span class=\"pre\">Session.objects.all().delete()</span></code>.</p>\n</aside>\n</section>\n<section id=\"writing-an-authentication-backend\">\n<h3>Écriture d’un moteur d’authentification<a class=\"heading-anchor\" href=\"#writing-an-authentication-backend\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Un moteur d’authentification est une classe qui implémente obligatoirement deux méthodes : <code class=\"docutils literal notranslate\"><span class=\"pre\">get_user(user_id)</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">authenticate(request,</span> <span class=\"pre\">**credentials)</span></code>. Facultativement, elle peut aussi implémenter un ensemble de <a class=\"reference internal\" href=\"#authorization-methods\"><span class=\"std std-ref\">méthodes d’autorisation</span></a> liées aux permissions.</p>\n<p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">get_user</span></code> accepte un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">user_id</span></code>, qui peut être un nom d’utilisateur, un identifiant de base de données ou toute autre valeur, mais qui doit représenter la clé primaire de votre objet utilisateur. Elle renvoie un objet utilisateur ou <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n<p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">authenticate</span></code> accepte un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">request</span></code> et des données d’authentification en paramètre. La plupart du temps, elle ressemblera à 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=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.backends</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseBackend</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyBackend</span><span class=\"p\">(</span><span class=\"n\">BaseBackend</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">authenticate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">username</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Check the username/password and return a user.</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>Mais elle pourrait aussi authentifier avec un jeton, 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=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.backends</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseBackend</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyBackend</span><span class=\"p\">(</span><span class=\"n\">BaseBackend</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">authenticate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">token</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Check the token and return a user.</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>D’une manière ou d’une autre, <code class=\"docutils literal notranslate\"><span class=\"pre\">authenticate()</span></code> doit vérifier les données d’authentification qu’elle reçoit et, dans le cas où ces données sont valides, elle doit renvoyer un objet utilisateur correspondant à ces données. Dans le cas contraire, elle doit renvoyer <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">request</span></code> est un objet <a class=\"reference internal\" href=\"/fr/5.1/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code></a> et peut valoir <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> s’il n’a pas été fourni à <a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.authenticate\" title=\"django.contrib.auth.authenticate\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">authenticate()</span></code></a> (laquelle le transmet au moteur d’authentification).</p>\n<p>Le site d’administration de Django est étroitement lié à l”<a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#user-objects\"><span class=\"std std-ref\">objet User</span></a> de Django. Par exemple, pour qu’un utilisateur puisse accéder au site, <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_staff\" title=\"django.contrib.auth.models.User.is_staff\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">User.is_staff</span></code></a> et <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active\" title=\"django.contrib.auth.models.User.is_active\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">User.is_active</span></code></a> doivent valoir <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> (voir <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/admin/#django.contrib.admin.AdminSite.has_permission\" title=\"django.contrib.admin.AdminSite.has_permission\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">AdminSite.has_permission()</span></code></a> pour plus de détails).</p>\n<p>La meilleure façon de gérer cela est de créer un objet Django <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> pour chaque utilisateur existant dans votre moteur (par ex. dans votre annuaire LDAP, votre base de données SQL externe, etc.). Vous pouvez soit écrire un script pour le faire de manière anticipée, soit déléguer à votre méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">authenticate</span></code> la création de l’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> lors de chaque première connexion.</p>\n<p>Voici un exemple de moteur qui s’authentifie en fonction de variables nom d’utilisateur et mot de passe définies dans votre fichier <code class=\"docutils literal notranslate\"><span class=\"pre\">settings.py</span></code> et crée un objet <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> de Django lors de la première authentification de l’utilisateur. Dans cet exemple, l’objet <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> de Django est créé comme superutilisateur ayant un accès complet au site d’administration :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">settings</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.backends</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseBackend</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.hashers</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">check_password</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">User</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">SettingsBackend</span><span class=\"p\">(</span><span class=\"n\">BaseBackend</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">    Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.</span>\n\n<span class=\"sd\">    Use the login name and a hash of the password. For example:</span>\n\n<span class=\"sd\">    ADMIN_LOGIN = &#39;admin&#39;</span>\n<span class=\"sd\">    ADMIN_PASSWORD = &#39;pbkdf2_sha256$30000$Vo0VlMnkR4Bk$qEvtdyZRWTcOsCnI/oQ7fVOu1XAURIZYoOZ3iq8Dr4M=&#39;</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">authenticate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">username</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"n\">login_valid</span> <span class=\"o\">=</span> <span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">ADMIN_LOGIN</span> <span class=\"o\">==</span> <span class=\"n\">username</span>\n        <span class=\"n\">pwd_valid</span> <span class=\"o\">=</span> <span class=\"n\">check_password</span><span class=\"p\">(</span><span class=\"n\">password</span><span class=\"p\">,</span> <span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">ADMIN_PASSWORD</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">login_valid</span> <span class=\"ow\">and</span> <span class=\"n\">pwd_valid</span><span class=\"p\">:</span>\n            <span class=\"k\">try</span><span class=\"p\">:</span>\n                <span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"n\">User</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">username</span><span class=\"o\">=</span><span class=\"n\">username</span><span class=\"p\">)</span>\n            <span class=\"k\">except</span> <span class=\"n\">User</span><span class=\"o\">.</span><span class=\"n\">DoesNotExist</span><span class=\"p\">:</span>\n                <span class=\"c1\"># Create a new user. There&#39;s no need to set a password</span>\n                <span class=\"c1\"># because only the password from settings.py is checked.</span>\n                <span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"n\">User</span><span class=\"p\">(</span><span class=\"n\">username</span><span class=\"o\">=</span><span class=\"n\">username</span><span class=\"p\">)</span>  <span class=\"c1\"># is_active defaults to True.</span>\n                <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">is_staff</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n                <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">is_superuser</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n                <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n            <span class=\"k\">return</span> <span class=\"n\">user</span>\n        <span class=\"k\">return</span> <span class=\"kc\">None</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_user</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">user_id</span><span class=\"p\">):</span>\n        <span class=\"k\">try</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"n\">User</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"n\">user_id</span><span class=\"p\">)</span>\n        <span class=\"k\">except</span> <span class=\"n\">User</span><span class=\"o\">.</span><span class=\"n\">DoesNotExist</span><span class=\"p\">:</span>\n            <span class=\"k\">return</span> <span class=\"kc\">None</span>\n</code></pre></div>\n</section>\n<section id=\"handling-authorization-in-custom-backends\">\n<span id=\"authorization-methods\"></span><h3>Gestion des autorisations dans les moteurs personnalisés<a class=\"heading-anchor\" href=\"#handling-authorization-in-custom-backends\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les moteurs d’authentification personnalisés peuvent fournir leurs propres permissions.</p>\n<p>Le modèle utilisateur et son gestionnaire délèguent les fonctions de consultation des permissions (<a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.get_user_permissions\" title=\"django.contrib.auth.models.User.get_user_permissions\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_user_permissions()</span></code></a>, <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.get_group_permissions\" title=\"django.contrib.auth.models.User.get_group_permissions\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_group_permissions()</span></code></a>, <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.get_all_permissions\" title=\"django.contrib.auth.models.User.get_all_permissions\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_all_permissions()</span></code></a>, <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.has_perm\" title=\"django.contrib.auth.models.User.has_perm\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">has_perm()</span></code></a>, <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.has_module_perms\" title=\"django.contrib.auth.models.User.has_module_perms\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">has_module_perms()</span></code></a> et <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.UserManager.with_perm\" title=\"django.contrib.auth.models.UserManager.with_perm\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">with_perm()</span></code></a>) à tout moteur d’authentification qui implémente ces fonctions.</p>\n<p>Les permissions données à l’utilisateur sera un surensemble de toutes les permissions renvoyées par tous les moteurs. Cela signifie que Django accorde une permission à un utilisateur pour autant qu’au moins un moteur le permette.</p>\n<p>Si un moteur génère une exception <a class=\"reference internal\" href=\"/fr/5.1/ref/exceptions/#django.core.exceptions.PermissionDenied\" title=\"django.core.exceptions.PermissionDenied\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">PermissionDenied</span></code></a> dans <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.has_perm\" title=\"django.contrib.auth.models.User.has_perm\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">has_perm()</span></code></a> ou <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.has_module_perms\" title=\"django.contrib.auth.models.User.has_module_perms\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">has_module_perms()</span></code></a>, l’autorisation échouera immédiatement et Django ne continuera pas avec les moteurs suivants.</p>\n<p>Un moteur pourrait implémenter les permissions pour l’administrateur « magique » 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=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.backends</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseBackend</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MagicAdminBackend</span><span class=\"p\">(</span><span class=\"n\">BaseBackend</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">has_perm</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">user_obj</span><span class=\"p\">,</span> <span class=\"n\">perm</span><span class=\"p\">,</span> <span class=\"n\">obj</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">user_obj</span><span class=\"o\">.</span><span class=\"n\">username</span> <span class=\"o\">==</span> <span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">ADMIN_LOGIN</span>\n</code></pre></div>\n<p>Cela accorde toutes les permissions à l’utilisateur dont l’accès a été accordé dans l’exemple précédent. Notez qu’en plus des mêmes paramètres passés aux fonctions associées à <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.models.User</span></code></a>, les fonctions du moteur d’authentification acceptent toutes en paramètre l’objet utilisateur, qui pourrait être l’utilisateur anonyme.</p>\n<p>Une implémentation complète des autorisations se trouve dans la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelBackend</span></code> dans <a class=\"extlink-source reference external\" href=\"https://github.com/django/django/blob/stable/5.1.x/django/contrib/auth/backends.py\">django/contrib/auth/backends.py</a>, qui constitue le moteur par défaut et interroge la plupart du temps la table <code class=\"docutils literal notranslate\"><span class=\"pre\">auth_permission</span></code>.</p>\n<section id=\"authorization-for-anonymous-users\">\n<span id=\"anonymous-auth\"></span><h4>Autorisation pour les utilisateurs anonymes<a class=\"heading-anchor\" href=\"#authorization-for-anonymous-users\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Un utilisateur anonyme est un utilisateur que ne s’est pas authentifié, c’est-à-dire qu’il n’a fourni aucun détail d’authentification valide. Cependant, cela ne signifie pas forcément qu’il ne reçoit aucune autorisation. Au niveau le plus élémentaire, la plupart des sites Web autorisent les utilisateurs anonymes à naviguer sur la plupart des pages du site, et certains autorisent également l’envoi de commentaires, etc.</p>\n<p>Le système de permissions de Django ne prévoit pas d’endroit où stocker des permissions pour les utilisateurs anonymes. Cependant, l’objet utilisateur transmis au moteur d’authentification peut être un objet <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.AnonymousUser\" title=\"django.contrib.auth.models.AnonymousUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.models.AnonymousUser</span></code></a> permettant au moteur de définir un comportement d’autorisation spécifique aux utilisateurs anonymes. C’est particulièrement utile pour les auteurs d’applications réutilisables qui peuvent déléguer toutes les questions d’autorisations au moteur d’authentification, plutôt que, par exemple, d’exiger des réglages pour contrôler les droits d’accès anonymes.</p>\n</section>\n<section id=\"authorization-for-inactive-users\">\n<span id=\"inactive-auth\"></span><h4>Autorisation pour les utilisateurs inactifs<a class=\"heading-anchor\" href=\"#authorization-for-inactive-users\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Un utilisateur inactif est un utilisateur dont le champ <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active\" title=\"django.contrib.auth.models.User.is_active\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">is_active</span></code></a> est défini à <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>. Les moteurs d’authentification <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.backends.ModelBackend\" title=\"django.contrib.auth.backends.ModelBackend\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ModelBackend</span></code></a> and <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.backends.RemoteUserBackend\" title=\"django.contrib.auth.backends.RemoteUserBackend\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">RemoteUserBackend</span></code></a> interdisent à ces utilisateurs de s’authentifier. Si un modèle d’utilisateur personnalisé ne possède pas de champ <a class=\"reference internal\" href=\"#django.contrib.auth.models.CustomUser.is_active\" title=\"django.contrib.auth.models.CustomUser.is_active\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">is_active</span></code></a>, tous les utilisateurs seront autorisés à s’authentifier.</p>\n<p>Vous pouvez utiliser <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.backends.AllowAllUsersModelBackend\" title=\"django.contrib.auth.backends.AllowAllUsersModelBackend\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AllowAllUsersModelBackend</span></code></a> ou <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.backends.AllowAllUsersRemoteUserBackend\" title=\"django.contrib.auth.backends.AllowAllUsersRemoteUserBackend\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AllowAllUsersRemoteUserBackend</span></code></a> si vous souhaitez permettre aux utilisateurs inactifs de s’authentifier.</p>\n<p>La prise en charge des utilisateurs anonymes dans le système des permissions permet d’imaginer un scénario où les utilisateurs anonymes ont certaines permissions que les utilisateurs authentifiés inactifs n’ont pas.</p>\n<p>N’oubliez pas de tester l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">is_active</span></code> de l’utilisateur dans les méthodes de votre propre moteur de permissions.</p>\n</section>\n<section id=\"handling-object-permissions\">\n<h4>Gestion des permissions sur les objets<a class=\"heading-anchor\" href=\"#handling-object-permissions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Le système de permissions de Django pose les fondations pour des permissions sur les objets, même s’il n’existe pas d’implémentation concrète dans le cœur de Django. Cela signifie que le contrôle des permissions sur les objets renvoie toujours <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> ou une liste vide (selon le contrôle effectué). Un moteur d’authentification reçoit les paramètres nommés <code class=\"docutils literal notranslate\"><span class=\"pre\">obj</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">user_obj</span></code> pour chaque méthode d’autorisation liée aux objets et peut renvoyer les permissions au niveau des objets comme il convient.</p>\n</section>\n</section>\n</section>\n<section id=\"custom-permissions\">\n<span id=\"id1\"></span><h2>Permissions personnalisées<a class=\"heading-anchor\" href=\"#custom-permissions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Pour créer des permissions personnalisées pour un objet modèle donné, utilisez l’<a class=\"reference internal\" href=\"/fr/5.1/topics/db/models/#meta-options\"><span class=\"std std-ref\">attribut Meta</span></a> <code class=\"docutils literal notranslate\"><span class=\"pre\">permissions</span></code> du modèle`.</p>\n<p>Ce modèle d’exemple <code class=\"docutils literal notranslate\"><span class=\"pre\">Task</span></code> crée deux permissions personnalisées, c’est-à-dire des actions que les utilisateurs peuvent effectuer ou non avec les instances <code class=\"docutils literal notranslate\"><span class=\"pre\">Task</span></code>, spécifiquement à votre application :</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=\"w\"> </span><span class=\"nc\">Task</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">permissions</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n            <span class=\"p\">(</span><span class=\"s2\">&quot;change_task_status&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Can change the status of tasks&quot;</span><span class=\"p\">),</span>\n            <span class=\"p\">(</span><span class=\"s2\">&quot;close_task&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;Can remove a task by setting its status as closed&quot;</span><span class=\"p\">),</span>\n        <span class=\"p\">]</span>\n</code></pre></div>\n<p>La seule conséquence de ce code est la création de ces permissions supplémentaires lors du lancement de <a class=\"reference internal\" href=\"/fr/5.1/ref/django-admin/#django-admin-migrate\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">manage.py</span> <span class=\"pre\">migrate</span></code></a> (la fonction qui crée les permissions est connectée au signal <a class=\"reference internal\" href=\"/fr/5.1/ref/signals/#django.db.models.signals.post_migrate\" title=\"django.db.models.signals.post_migrate\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">post_migrate</span></code></a>). Votre code a ensuite la charge de contrôler la valeur de ces permissions lorsqu’un utilisateur essaie d’accéder à la fonctionnalité fournie par l’application (modification de l’état des tâches ou fermeture des tâches). En poursuivant sur l’exemple précédent, le code suivant contrôle si un utilisateur peut fermer les tâches :</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=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">has_perm</span><span class=\"p\">(</span><span class=\"s2\">&quot;app.close_task&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"extending-the-existing-user-model\">\n<span id=\"extending-user\"></span><h2>Extension du modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> existant<a class=\"heading-anchor\" href=\"#extending-the-existing-user-model\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Il existe deux manières d’étendre le modèle <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a> par défaut sans le substituer par votre propre modèle. Si les modifications requises sont purement comportementales et ne nécessitent pas de modifier ce qui est stocké dans la base de données, vous pouvez créer un <a class=\"reference internal\" href=\"/fr/5.1/topics/db/models/#proxy-models\"><span class=\"std std-ref\">modèle mandataire</span></a> basé sur <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a>. Ceci expose toutes les fonctionnalités offertes par les modèles mandataires, y compris l’ordre de tri par défaut, les gestionnaires personnalisés ou les méthodes de modèle personnalisées.</p>\n<p>Si vous souhaitez stocker des informations liées au modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code>, vous pouvez utiliser une relation <a class=\"reference internal\" href=\"/fr/5.1/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">OneToOneField</span></code></a> vers un modèle contenant les champs correspondant aux informations supplémentaires. Ce modèle un-à-un est souvent appelé un modèle de profil, car il peut stocker des informations non liées à l’authentification au sujet d’un utilisateur du site. Par exemple, vous pouvez créer un modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">Employee</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">User</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Employee</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">OneToOneField</span><span class=\"p\">(</span><span class=\"n\">User</span><span class=\"p\">,</span> <span class=\"n\">on_delete</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CASCADE</span><span class=\"p\">)</span>\n    <span class=\"n\">department</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>En supposant qu’il existe un employé Fred Smith référencé à la fois par un modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> et un modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">Employee</span></code>, vous pouvez accéder aux informations liées en utilisant les conventions standards des modèles liés de Django :</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">u</span> <span class=\"o\">=</span> <span class=\"n\">User</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">username</span><span class=\"o\">=</span><span class=\"s2\">&quot;fsmith&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">freds_department</span> <span class=\"o\">=</span> <span class=\"n\">u</span><span class=\"o\">.</span><span class=\"n\">employee</span><span class=\"o\">.</span><span class=\"n\">department</span>\n</code></pre></div>\n<p>Pour ajouter les champs du modèle de profil à la page de l’utilisateur dans l’interface d’administration, définissez un <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin\" title=\"django.contrib.admin.InlineModelAdmin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">InlineModelAdmin</span></code></a> (pour cet exemple, nous utiliserons un <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/admin/#django.contrib.admin.StackedInline\" title=\"django.contrib.admin.StackedInline\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">StackedInline</span></code></a>) dans le fichier <code class=\"docutils literal notranslate\"><span class=\"pre\">admin.py</span></code> de votre application et ajoutez-le à une classe <code class=\"docutils literal notranslate\"><span class=\"pre\">UserAdmin</span></code> qui sera enregistrée avec la classe <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></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=\"w\"> </span><span class=\"nn\">django.contrib</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">admin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.admin</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">UserAdmin</span> <span class=\"k\">as</span> <span class=\"n\">BaseUserAdmin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">User</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">my_user_profile_app.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Employee</span>\n\n\n<span class=\"c1\"># Define an inline admin descriptor for Employee model</span>\n<span class=\"c1\"># which acts a bit like a singleton</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">EmployeeInline</span><span class=\"p\">(</span><span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">StackedInline</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Employee</span>\n    <span class=\"n\">can_delete</span> <span class=\"o\">=</span> <span class=\"kc\">False</span>\n    <span class=\"n\">verbose_name_plural</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;employee&quot;</span>\n\n\n<span class=\"c1\"># Define a new User admin</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">UserAdmin</span><span class=\"p\">(</span><span class=\"n\">BaseUserAdmin</span><span class=\"p\">):</span>\n    <span class=\"n\">inlines</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">EmployeeInline</span><span class=\"p\">]</span>\n\n\n<span class=\"c1\"># Re-register UserAdmin</span>\n<span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">site</span><span class=\"o\">.</span><span class=\"n\">unregister</span><span class=\"p\">(</span><span class=\"n\">User</span><span class=\"p\">)</span>\n<span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">site</span><span class=\"o\">.</span><span class=\"n\">register</span><span class=\"p\">(</span><span class=\"n\">User</span><span class=\"p\">,</span> <span class=\"n\">UserAdmin</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Ces modèles de profil n’ont aucune particularité, ce ne sont que des modèles Django qui possèdent un lien un-à-un avec un modèle d’utilisateur. En tant que tels, ils ne sont pas automatiquement créés lorsqu’un utilisateur est créé, mais il est possible de profiter du signal <a class=\"reference internal\" href=\"/fr/5.1/ref/signals/#django.db.models.signals.post_save\" title=\"django.db.models.signals.post_save\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.post_save</span></code></a> pour créer ou mettre à jour les modèles liés selon les besoins.</p>\n<p>L’utilisation de modèles liés provoque des requêtes ou des jointures supplémentaires pour récupérer les données liées. En fonction de vos besoins, il peut être préférable d’utiliser un modèle d’utilisateur personnalisé possédant les champs liés supplémentaires. Cependant, des liens existants vers le modèle d’utilisateur par défaut dans les applications de votre projet pourraient justifier la charge supplémentaire sur la base de données.</p>\n</section>\n<section id=\"substituting-a-custom-user-model\">\n<span id=\"auth-custom-user\"></span><h2>Substitution par un modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> personnalisé<a class=\"heading-anchor\" href=\"#substituting-a-custom-user-model\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Certains types de projets ont des exigences en terme d’authentification pour lesquelles le modèle <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a> intégré de Django ne convient pas toujours. Par exemple, certains sites préfèrent utiliser l’adresse électronique comme identifiant d’identification plutôt qu’un nom d’utilisateur.</p>\n<p>Django permet de surcharger le modèle d’utilisateur par défaut en attribuant une valeur au réglage <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a> se référant à un modèle personnalisé :</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=\"n\">AUTH_USER_MODEL</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;myapp.MyUser&quot;</span>\n</code></pre></div>\n<p>Cette syntaxe pointée spécifie le attr:~django.apps.AppConfig.label de l’application Django (qui doit figurer dans <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a>) et le nom du modèle Django que vous souhaitez utiliser comme modèle d’utilisateur.</p>\n<section id=\"using-a-custom-user-model-when-starting-a-project\">\n<h3>Utilisation d’un modèle d’utilisateur personnalisé au départ d’un projet<a class=\"heading-anchor\" href=\"#using-a-custom-user-model-when-starting-a-project\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous démarrez un nouveau projet, vous pouvez définir un modèle d’utilisateur personnalisé ayant le même comportement que le modèle par défaut en héritant de  <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractUser\" title=\"django.contrib.auth.models.AbstractUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractUser</span></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=\"w\"> </span><span class=\"nn\">django.contrib.auth.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">AbstractUser</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">User</span><span class=\"p\">(</span><span class=\"n\">AbstractUser</span><span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n</code></pre></div>\n<p>N’oubliez pas de faire pointer <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a> vers ce modèle. Faites-le avant de créer les premières migrations ou de lancer <code class=\"docutils literal notranslate\"><span class=\"pre\">manage.py</span> <span class=\"pre\">migrate</span></code> pour la première fois.</p>\n<p>De plus, inscrivez le modèle dans le fichier <code class=\"docutils literal notranslate\"><span class=\"pre\">admin.py</span></code> de l’application :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">admin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.admin</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">UserAdmin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">User</span>\n\n<span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">site</span><span class=\"o\">.</span><span class=\"n\">register</span><span class=\"p\">(</span><span class=\"n\">User</span><span class=\"p\">,</span> <span class=\"n\">UserAdmin</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"changing-to-a-custom-user-model-mid-project\">\n<h3>Conversion vers un modèle d’utilisateur personnalisé en cours de projet<a class=\"heading-anchor\" href=\"#changing-to-a-custom-user-model-mid-project\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>La modification de <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a> après avoir créé les tables de base de données est possible mais peut se révéler complexe, car cela affecte les clés étrangères et les relations plusieurs-à-plusieurs, par exemple.</p>\n<p>Cette modification ne peut pas être automatisée et nécessite une intervention manuelle sur le schéma, en déplaçant les données depuis l’ancienne table des utilisateurs et peut-être même en réappliquant manuellement certaines migrations. Voir <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/25313\">#25313</a> pour un aperçu des étapes à suivre.</p>\n<p>En raison des limites de Django liées à la fonctionnalité de dépendance dynamique pour les modèles remplaçables à chaud, le modèle référencé par <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a> doit être créé lors de la première migration de son application (généralement appelée <code class=\"docutils literal notranslate\"><span class=\"pre\">0001_initial</span></code>) ; sinon, vous aurez des problèmes de dépendances.</p>\n<p>En outre, vous pouvez rencontrer une erreur <code class=\"docutils literal notranslate\"><span class=\"pre\">CircularDependencyError</span></code> lors de l’exécution des migrations lorsque Django n’est pas en mesure de briser automatiquement la boucle de dépendance en raison de la dépendance dynamique. Si vous rencontrez cette erreur, vous devez rompre la boucle en déplaçant les modèles dont dépend votre modèle d’utilisateur dans une deuxième migration (vous pouvez essayer de faire deux modèles normaux qui ont une clé <code class=\"docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></code> l’un vers l’autre et voir comment <code class=\"docutils literal notranslate\"><span class=\"pre\">makemigrations</span></code> résout la dépendance circulaire si vous voulez voir comment cela se passe habituellement).</p>\n</section>\n<section id=\"reusable-apps-and-auth-user-model\">\n<h3>Applications réutilisables et <code class=\"docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code><a class=\"heading-anchor\" href=\"#reusable-apps-and-auth-user-model\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les applications réutilisables ne devraient pas implémenter de modèle d’utilisateur personnalisé. Un projet peut utiliser beaucoup d’applications, et deux applications réutilisables qui implémenteraient chacune un modèle d’utilisateur personnalisé ne pourraient pas être utilisées conjointement. Si vous avez besoin de stocker des informations liées aux utilisateurs dans une application, utilisez une liaison <a class=\"reference internal\" href=\"/fr/5.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></code></a> ou <a class=\"reference internal\" href=\"/fr/5.1/ref/models/fields/#django.db.models.OneToOneField\" title=\"django.db.models.OneToOneField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">OneToOneField</span></code></a> vers <code class=\"docutils literal notranslate\"><span class=\"pre\">settings.AUTH_USER_MODEL</span></code> comme expliqué ci-dessous.</p>\n</section>\n<section id=\"referencing-the-user-model\">\n<h3>Références au modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code><a class=\"heading-anchor\" href=\"#referencing-the-user-model\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous référencez directement <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a> (par exemple dans une clé étrangère), votre code ne fonctionnera pas dans des projets où le réglage <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a> a été défini à un autre modèle d’utilisateur.</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.get_user_model\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_user_model</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.get_user_model\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Au lieu de faire directement référence à  <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a>, il est préférable de référencer le modèle d’utilisateur en utilisant <code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.get_user_model()</span></code>. Cette méthode renvoie le modèle d’utilisateur actuellement actif, soit le modèle personnalisé s’il a été défini, soit <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a>.</p>\n<p>Lorsque vous définissez une clé étrangère ou des relations plusieurs-à-plusieurs vers le modèle d’utilisateur, vous devriez indiquer le modèle personnalisé au moyen du réglage <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a>. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">settings</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Article</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">author</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ForeignKey</span><span class=\"p\">(</span>\n        <span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">AUTH_USER_MODEL</span><span class=\"p\">,</span>\n        <span class=\"n\">on_delete</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CASCADE</span><span class=\"p\">,</span>\n    <span class=\"p\">)</span>\n</code></pre></div>\n<p>Lorsque vous vous connectez aux signaux envoyés par le modèle d’utilisateur, vous devriez indiquer le modèle personnalisé au moyen du réglage <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a>. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">settings</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models.signals</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">post_save</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">post_save_receiver</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"p\">,</span> <span class=\"n\">instance</span><span class=\"p\">,</span> <span class=\"n\">created</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"k\">pass</span>\n\n\n<span class=\"n\">post_save</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"n\">post_save_receiver</span><span class=\"p\">,</span> <span class=\"n\">sender</span><span class=\"o\">=</span><span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">AUTH_USER_MODEL</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>En règle générale, il est plus facile de se référer au modèle d’utilisateur avec le réglage <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a> dans tout code exécuté au moment de l’importation. Cependant, il est aussi possible d’appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">get_user_model()</span></code> pendant que Django est en train d’importer les modèles. Il est donc possible d’écrire <code class=\"docutils literal notranslate\"><span class=\"pre\">models.ForeignKey(get_user_model(),</span> <span class=\"pre\">...)</span></code>.</p>\n<p>Si votre application est testée avec plusieurs modèles d’utilisateur, par exemple en utilisant <code class=\"docutils literal notranslate\"><span class=\"pre\">&#64;override_settings(AUTH_USER_MODEL=...)</span></code>, et que vous conserviez en cache le résultat de <code class=\"docutils literal notranslate\"><span class=\"pre\">get_user_model()</span></code> dans une variable au niveau du module, il serait alors nécessaire d’écouter le signal  <a class=\"reference internal\" href=\"/fr/5.1/ref/signals/#django.test.signals.setting_changed\" title=\"django.test.signals.setting_changed\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">setting_changed</span></code></a> pour réinitialiser le cache. Par exemple :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.apps</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">apps</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">get_user_model</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.signals</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">setting_changed</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.dispatch</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">receiver</span>\n\n\n<span class=\"nd\">@receiver</span><span class=\"p\">(</span><span class=\"n\">setting_changed</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">user_model_swapped</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"p\">,</span> <span class=\"n\">setting</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">setting</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;AUTH_USER_MODEL&quot;</span><span class=\"p\">:</span>\n        <span class=\"n\">apps</span><span class=\"o\">.</span><span class=\"n\">clear_cache</span><span class=\"p\">()</span>\n        <span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">some_module</span>\n\n        <span class=\"n\">some_module</span><span class=\"o\">.</span><span class=\"n\">UserModel</span> <span class=\"o\">=</span> <span class=\"n\">get_user_model</span><span class=\"p\">()</span>\n</code></pre></div>\n</dd></dl>\n\n</section>\n<section id=\"specifying-a-custom-user-model\">\n<span id=\"specifying-custom-user-model\"></span><h3>Indication d’une modèle d’utilisateur personnalisé<a class=\"heading-anchor\" href=\"#specifying-a-custom-user-model\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Lorsque vous démarrez votre projet avec votre propre modèle d’utilisateur, prenez le temps de considérer s’il s’agit du bon choix pour votre projet.</p>\n<p>En conservant toutes les informations liées à un utilisateur dans un seul modèle, on évite de devoir faire recours à des requêtes de base de données supplémentaires ou plus complexes pour récupérer d’éventuels modèles liés. D’un autre côté, il peut être plus adéquat de stocker les informations utilisateurs spécifiques à une application dans un modèle ayant une relation avec le modèle utilisateur personnalisé. Cela permet à chaque application de définir ses propres exigences en terme de données utilisateurs sans risquer de potentiels conflits ou de casser des comportements attendus par d’autres applications. Cela permet aussi de conserver le modèle utilisateur aussi simple que possible, ciblé sur l’authentification et se limitant aux exigences minimales que Django attend des modèles utilisateurs personnalisés.</p>\n<p>Si vous utilisez le moteur d’authentification par défaut, le modèle doit alors comporter un seul champ unique pouvant être utilisé pour l’identification. Cela peut être un nom d’utilisateur, une adresse électronique ou tout autre attribut unique. Un champ de nom d’utilisateur non unique est autorisé si vous utilisez un moteur d’authentification personnalisé qui le prend en charge.</p>\n<p>La manière la plus simple de construire un modèle d’utilisateur personnalisé en respectant les contraintes est d’hériter de <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></a>. La classe <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></a> fournit l’implémentation de base d’un modèle d’utilisateur, y compris les mots de passe hachés et les jetons de réinitialisation des mots de passe. Vous devez ensuite fournir les détails d’implémentation critiques :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUser\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">models.</span></span><span class=\"sig-name descname\"><span class=\"pre\">CustomUser</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUser\"><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.contrib.auth.models.CustomUser.USERNAME_FIELD\">\n<span class=\"sig-name descname\"><span class=\"pre\">USERNAME_FIELD</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUser.USERNAME_FIELD\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Une chaîne contenant le nom du champ du modèle d’utilisateur utilisé comme identifiant unique. C’est normalement quelque chose comme un nom d’utilisateur ou une adresse électronique, ou encore tout autre identifiant unique. Ce champ <em>doit</em> être unique (par ex. avoir <code class=\"docutils literal notranslate\"><span class=\"pre\">unique=True</span></code> dans sa définition), sauf dans le cas où vous utilisez un moteur d’authentification personnalisé qui sait gérer les noms d’utilisateur non uniques.</p>\n<p>Dans l’exemple suivant, le champ <code class=\"docutils literal notranslate\"><span class=\"pre\">identifier</span></code> est utilisé comme champ d’identification :</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=\"w\"> </span><span class=\"nc\">MyUser</span><span class=\"p\">(</span><span class=\"n\">AbstractBaseUser</span><span class=\"p\">):</span>\n    <span class=\"n\">identifier</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">40</span><span class=\"p\">,</span> <span class=\"n\">unique</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n    <span class=\"o\">...</span>\n    <span class=\"n\">USERNAME_FIELD</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;identifier&quot;</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUser.EMAIL_FIELD\">\n<span class=\"sig-name descname\"><span class=\"pre\">EMAIL_FIELD</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUser.EMAIL_FIELD\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Une chaîne décrivant le nom du champ courriel du modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code>. Cette valeur est renvoyée par <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser.get_email_field_name\" title=\"django.contrib.auth.models.AbstractBaseUser.get_email_field_name\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_email_field_name()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUser.REQUIRED_FIELDS\">\n<span class=\"sig-name descname\"><span class=\"pre\">REQUIRED_FIELDS</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUser.REQUIRED_FIELDS\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Une liste de noms de champs qui devront être renseignés lors de la création d’un utilisateur par la commande de gestion <a class=\"reference internal\" href=\"/fr/5.1/ref/django-admin/#django-admin-createsuperuser\"><code class=\"xref std std-djadmin docutils literal notranslate\"><span class=\"pre\">createsuperuser</span></code></a>. La commande demandera de fournir une valeur pour chacun de ces champs. Cette liste doit contenir tous les champs pour lesquels l’attribut  <a class=\"reference internal\" href=\"/fr/5.1/ref/models/fields/#django.db.models.Field.blank\" title=\"django.db.models.Field.blank\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">blank</span></code></a> est <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> ou non défini, et peut inclure des champs supplémentaires pour lesquels vous souhaitez que l’utilisateur donne une valeur lorsqu’un utilisateur est créé de manière interactive. <code class=\"docutils literal notranslate\"><span class=\"pre\">REQUIRED_FIELDS</span></code> n’a aucun effet dans d’autres parties de Django, comme lors de la création d’un utilisateur par l’interface d’administration.</p>\n<p>Par exemple, voici la définition partielle d’un modèle d’utilisateur définissant deux champs obligatoires, une date de naissance et une hauteur :</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=\"w\"> </span><span class=\"nc\">MyUser</span><span class=\"p\">(</span><span class=\"n\">AbstractBaseUser</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    <span class=\"n\">date_of_birth</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n    <span class=\"n\">height</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">FloatField</span><span class=\"p\">()</span>\n    <span class=\"o\">...</span>\n    <span class=\"n\">REQUIRED_FIELDS</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;date_of_birth&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;height&quot;</span><span class=\"p\">]</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">REQUIRED_FIELDS</span></code> doit contenir tous les champs obligatoires de votre modèle d’utilisateur, mais ne doit <em>pas</em> contenir le champ <code class=\"docutils literal notranslate\"><span class=\"pre\">USERNAME_FIELD</span></code> ni le champ <code class=\"docutils literal notranslate\"><span class=\"pre\">password</span></code> car de toute façon, il faudra fournir des valeurs pour ces champs.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUser.is_active\">\n<span class=\"sig-name descname\"><span class=\"pre\">is_active</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUser.is_active\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Un attribut booléen indiquant si l’utilisateur est considéré comme « actif ». Cet attribut est fournit comme attribut de <code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code> et valant <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> par défaut. La manière dont vous allez l’implémenter dépendra des détails des moteurs d’authentification choisis. Consultez la documentation de l’<a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active\" title=\"django.contrib.auth.models.User.is_active\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">attribut</span> <span class=\"pre\">is_active</span></code></a> du modèle d’utilisateur intégré pour plus de détails.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUser.get_full_name\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_full_name</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUser.get_full_name\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Facultatif. Un identifiant formel plus long pour l’utilisateur comme par exemple son nom complet. Si implémenté, il apparaît avec le nom d’utilisateur dans l’historique d’objets dans <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/admin/#module-django.contrib.admin\" title=\"django.contrib.admin: Django's admin site.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.admin</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUser.get_short_name\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_short_name</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUser.get_short_name\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Facultatif. Un identifiant informel court pour l’utilisateur comme par exemple son prénom. Si implémenté, il remplace le nom d’utilisateur dans la salutation de l’utilisateur dans l’en-tête du site <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/admin/#module-django.contrib.admin\" title=\"django.contrib.admin: Django's admin site.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.admin</span></code></a>.</p>\n</dd></dl>\n\n<aside class=\"admonition-importing-abstractbaseuser admonition\">\n<p class=\"admonition-title\">Importation de <code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">BaseUserManager</span></code> peuvent être importés à partir de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.base_user</span></code> afin qu’ils puissent être importés sans devoir inclure <code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.auth</span></code> dans <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-INSTALLED_APPS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">INSTALLED_APPS</span></code></a>.</p>\n</aside>\n</dd></dl>\n\n<p>Les méthodes et attributs suivants sont disponibles pour chaque sous-classe de <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></a>:</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">models.</span></span><span class=\"sig-name descname\"><span class=\"pre\">AbstractBaseUser</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.get_username\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_username</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.get_username\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie la valeur du champ spécifié dans <code class=\"docutils literal notranslate\"><span class=\"pre\">USERNAME_FIELD</span></code>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.clean\">\n<span class=\"sig-name descname\"><span class=\"pre\">clean</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.clean\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Normalise le nom d’utilisateur en appelant <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser.normalize_username\" title=\"django.contrib.auth.models.AbstractBaseUser.normalize_username\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">normalize_username()</span></code></a>. Si vous surchargez cette méthode, prenez soin d’appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">super()</span></code> pour conserver la normalisation.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.get_email_field_name\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">classmethod</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">get_email_field_name</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.get_email_field_name\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie le nom du champ courriel désigné par l’attribut <a class=\"reference internal\" href=\"#django.contrib.auth.models.CustomUser.EMAIL_FIELD\" title=\"django.contrib.auth.models.CustomUser.EMAIL_FIELD\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">EMAIL_FIELD</span></code></a>. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">EMAIL_FIELD</span></code> n’est pas renseigné, renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">'email'</span></code> par défaut.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.normalize_username\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">classmethod</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">normalize_username</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">username</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.normalize_username\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Applique la normalisation Unicode NFKC aux noms d’utilisateurs afin que des caractères visuellement identiques avec des points de code Unicode différents soient considérés identiques.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.is_authenticated\">\n<span class=\"sig-name descname\"><span class=\"pre\">is_authenticated</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.is_authenticated\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Attribut en lecture seule qui vaut toujours <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> (contrairement à <code class=\"docutils literal notranslate\"><span class=\"pre\">AnonymousUser.is_authenticated</span></code> qui vaut toujours <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>). C’est une façon de savoir si l’utilisateur a été authentifié. Aucune permission n’est prise en compte et il n’y a pas de contrôle sur le drapeau <code class=\"docutils literal notranslate\"><span class=\"pre\">is_active</span></code> de l’utilisateur ou sur la validité de la session. Même si cet attribut est généralement consulté pour <code class=\"docutils literal notranslate\"><span class=\"pre\">request.user</span></code> afin de déterminer s’il a été défini par <a class=\"reference internal\" href=\"/fr/5.1/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware\" title=\"django.contrib.auth.middleware.AuthenticationMiddleware\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AuthenticationMiddleware</span></code></a> (représentant l’utilisateur actuellement connecté), vous devez savoir que cet attribut vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> pour toute instance de <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.is_anonymous\">\n<span class=\"sig-name descname\"><span class=\"pre\">is_anonymous</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.is_anonymous\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Attribut en lecture seule qui vaut toujours <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>. C’est une façon de différencier les objets <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a> des objets <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.AnonymousUser\" title=\"django.contrib.auth.models.AnonymousUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AnonymousUser</span></code></a>. Généralement, il vaut mieux utiliser <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_authenticated\" title=\"django.contrib.auth.models.User.is_authenticated\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">is_authenticated</span></code></a> que cet attribut.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.set_password\">\n<span class=\"sig-name descname\"><span class=\"pre\">set_password</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">raw_password</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.set_password\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Définit le mot de passe de l’utilisateur à la chaîne brute indiquée, en se chargeant du hachage du mot de passe. L’objet <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></a> n’est pas enregistré par cette méthode.</p>\n<p>Lorsque <code class=\"docutils literal notranslate\"><span class=\"pre\">raw_password</span></code> vaut <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>, le mot de passe sera défini comme non utilisable, comme si on avait appelé <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser.set_unusable_password\" title=\"django.contrib.auth.models.AbstractBaseUser.set_unusable_password\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">set_unusable_password()</span></code></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.check_password\">\n<span class=\"sig-name descname\"><span class=\"pre\">check_password</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">raw_password</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.check_password\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.acheck_password\">\n<span class=\"sig-name descname\"><span class=\"pre\">acheck_password</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">raw_password</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.acheck_password\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p><em>Version asynchrone</em>: <code class=\"docutils literal notranslate\"><span class=\"pre\">acheck_password()</span></code></p>\n<p>Renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si la chaîne brute transmise est le mot de passe correct de cet utilisateur (cette méthode se charge du hachage du mot de passe en vue de la comparaison).</p>\n<aside class=\"version-note version-changed\" data-version=\"5.0\">\n<p class=\"version-note-title\">Changed in Django 5.0</p><p>La méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">acheck_password()</span></code> a été ajoutée.</p>\n</aside>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.set_unusable_password\">\n<span class=\"sig-name descname\"><span class=\"pre\">set_unusable_password</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.set_unusable_password\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Marque l’utilisateur comme n’ayant pas de mot de passe défini. Ce n’est pas la même chose que de définir une chaîne vide comme mot de passe. <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser.check_password\" title=\"django.contrib.auth.models.AbstractBaseUser.check_password\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">check_password()</span></code></a> ne renvoie jamais <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> pour cet utilisateur. L’objet <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></a> n’est pas enregistré par cette méthode.</p>\n<p>Cela peut être utile si le processus d’authentification de votre application se fait par une source externe existante telle qu’un annuaire LDAP.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.has_usable_password\">\n<span class=\"sig-name descname\"><span class=\"pre\">has_usable_password</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.has_usable_password\"><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\"><span class=\"pre\">False</span></code> si <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser.set_unusable_password\" title=\"django.contrib.auth.models.AbstractBaseUser.set_unusable_password\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">set_unusable_password()</span></code></a> a été appelée pour cet utilisateur.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_session_auth_hash</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.get_session_auth_hash\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie une empreinte HMAC du champ de mot de passe. Utilisé pour <a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#session-invalidation-on-password-change\"><span class=\"std std-ref\">Invalidation de session lors du changement de mot de passe</span></a>.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractBaseUser.get_session_auth_fallback_hash\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_session_auth_fallback_hash</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractBaseUser.get_session_auth_fallback_hash\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Produit l’empreinte HMAC du champ mot de passe en utilisant <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-SECRET_KEY_FALLBACKS\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">SECRET_KEY_FALLBACKS</span></code></a>. Utilisé par <code class=\"docutils literal notranslate\"><span class=\"pre\">get_user()</span></code>.</p>\n</dd></dl>\n\n</dd></dl>\n\n<p><a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractUser\" title=\"django.contrib.auth.models.AbstractUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractUser</span></code></a> hérite de <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></a>:</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractUser\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">models.</span></span><span class=\"sig-name descname\"><span class=\"pre\">AbstractUser</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractUser\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.AbstractUser.clean\">\n<span class=\"sig-name descname\"><span class=\"pre\">clean</span></span><span class=\"sig-paren\">(</span><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.AbstractUser.clean\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Normalise l’adresse électronique en appelant <a class=\"reference internal\" href=\"#django.contrib.auth.models.BaseUserManager.normalize_email\" title=\"django.contrib.auth.models.BaseUserManager.normalize_email\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">BaseUserManager.normalize_email()</span></code></a>. Si vous surchargez cette méthode, prenez soin d’appeler <code class=\"docutils literal notranslate\"><span class=\"pre\">super()</span></code> pour conserver la normalisation.</p>\n</dd></dl>\n\n</dd></dl>\n\n</section>\n<section id=\"writing-a-manager-for-a-custom-user-model\">\n<h3>Écriture d’un gestionnaire pour un modèle d’utilisateur personnalisé<a class=\"heading-anchor\" href=\"#writing-a-manager-for-a-custom-user-model\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il faudrait aussi définir un gestionnaire personnalisé pour votre modèle d’utilisateur. Si ce dernier définit les champs <code class=\"docutils literal notranslate\"><span class=\"pre\">username</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">email</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">is_staff</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">is_active</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">is_superuser</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">last_login</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">date_joined</span></code> comparables au modèle d’utilisateur par défaut de Django, vous pouvez utiliser le gestionnaire <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.UserManager\" title=\"django.contrib.auth.models.UserManager\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">UserManager</span></code></a> de Django. Cependant, si votre modèle d’utilisateur définit des champs différents, vous devrez définir un gestionnaire personnalisé héritant de <a class=\"reference internal\" href=\"#django.contrib.auth.models.BaseUserManager\" title=\"django.contrib.auth.models.BaseUserManager\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BaseUserManager</span></code></a> et fournissant deux méthodes supplémentaires :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUserManager\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">models.</span></span><span class=\"sig-name descname\"><span class=\"pre\">CustomUserManager</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUserManager\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUserManager.create_user\">\n<span class=\"sig-name descname\"><span class=\"pre\">create_user</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">username_field</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">password</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">other_fields</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUserManager.create_user\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le prototype de <code class=\"docutils literal notranslate\"><span class=\"pre\">create_user()</span></code> doit accepter en paramètre le champ nom d’utilisateur ainsi que tous les champs obligatoires. Par exemple, si votre modèle d’utilisateur utilise <code class=\"docutils literal notranslate\"><span class=\"pre\">email</span></code> comme champ nom d’utilisateur et que <code class=\"docutils literal notranslate\"><span class=\"pre\">date_of_birth</span></code> est un champ obligatoire, <code class=\"docutils literal notranslate\"><span class=\"pre\">create_user</span></code> devrait être définie ainsi :</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=\"w\"> </span><span class=\"nf\">create_user</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">email</span><span class=\"p\">,</span> <span class=\"n\">date_of_birth</span><span class=\"p\">,</span> <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"c1\"># create user here</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.CustomUserManager.create_superuser\">\n<span class=\"sig-name descname\"><span class=\"pre\">create_superuser</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">username_field</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">password</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">other_fields</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.CustomUserManager.create_superuser\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Le prototype de <code class=\"docutils literal notranslate\"><span class=\"pre\">create_superuser()</span></code> doit accepter en paramètre le champ nom d’utilisateur ainsi que tous les champs obligatoires. Par exemple, si votre modèle d’utilisateur utilise <code class=\"docutils literal notranslate\"><span class=\"pre\">email</span></code> comme champ nom d’utilisateur et que <code class=\"docutils literal notranslate\"><span class=\"pre\">date_of_birth</span></code> est un champ obligatoire, <code class=\"docutils literal notranslate\"><span class=\"pre\">create_superuser</span></code> devrait être définie ainsi :</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=\"w\"> </span><span class=\"nf\">create_superuser</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">email</span><span class=\"p\">,</span> <span class=\"n\">date_of_birth</span><span class=\"p\">,</span> <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n    <span class=\"c1\"># create superuser here</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</dd></dl>\n\n</dd></dl>\n\n<p>Pour une clé étrangère <a class=\"reference internal\" href=\"/fr/5.1/ref/models/fields/#django.db.models.ForeignKey\" title=\"django.db.models.ForeignKey\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ForeignKey</span></code></a> dans <a class=\"reference internal\" href=\"#django.contrib.auth.models.CustomUser.USERNAME_FIELD\" title=\"django.contrib.auth.models.CustomUser.USERNAME_FIELD\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">USERNAME_FIELD</span></code></a> ou <a class=\"reference internal\" href=\"#django.contrib.auth.models.CustomUser.REQUIRED_FIELDS\" title=\"django.contrib.auth.models.CustomUser.REQUIRED_FIELDS\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">REQUIRED_FIELDS</span></code></a>, ces méthodes reçoivent la valeur de <a class=\"reference internal\" href=\"/fr/5.1/ref/models/fields/#django.db.models.ForeignKey.to_field\" title=\"django.db.models.ForeignKey.to_field\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">to_field</span></code></a> (la clé primaire <a class=\"reference internal\" href=\"/fr/5.1/ref/models/fields/#django.db.models.Field.primary_key\" title=\"django.db.models.Field.primary_key\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">primary_key</span></code></a> par défaut) d’une instance existante.</p>\n<p><a class=\"reference internal\" href=\"#django.contrib.auth.models.BaseUserManager\" title=\"django.contrib.auth.models.BaseUserManager\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">BaseUserManager</span></code></a> fournit les méthodes utilitaires suivantes :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.BaseUserManager\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">models.</span></span><span class=\"sig-name descname\"><span class=\"pre\">BaseUserManager</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.BaseUserManager\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.BaseUserManager.normalize_email\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">classmethod</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">normalize_email</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">email</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.BaseUserManager.normalize_email\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Normalise les adresses électroniques en transformant en minuscules la partie nom de domaine de l’adresse.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.BaseUserManager.get_by_natural_key\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_by_natural_key</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">username</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.BaseUserManager.get_by_natural_key\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Récupère une instance utilisateur en utilisant le contenu du champ spécifié dans <code class=\"docutils literal notranslate\"><span class=\"pre\">USERNAME_FIELD</span></code>.</p>\n</dd></dl>\n\n</dd></dl>\n\n</section>\n<section id=\"extending-django-s-default-user\">\n<h3>Extension du modèle <code class=\"docutils literal notranslate\"><span class=\"pre\">User</span></code> par défaut de Django<a class=\"heading-anchor\" href=\"#extending-django-s-default-user\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si le modèle <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a> de Django vous convient entièrement mais que vous voulez ajouter quelques informations de profil supplémentaires, créez une sous-classe de <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractUser\" title=\"django.contrib.auth.models.AbstractUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.models.AbstractUser</span></code></a> et ajoutez vos propres champs de profil. Il est toutefois conseillé de créer un modèle séparé, comme indiqué dans <a class=\"reference internal\" href=\"#specifying-custom-user-model\"><span class=\"std std-ref\">Indication d’une modèle d’utilisateur personnalisé</span></a>. <code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractUser</span></code> fournit une implémentation complète du modèle <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a> par défaut sous forme de <a class=\"reference internal\" href=\"/fr/5.1/topics/db/models/#abstract-base-classes\"><span class=\"std std-ref\">modèle abstrait</span></a>.</p>\n</section>\n<section id=\"custom-users-and-the-built-in-auth-forms\">\n<span id=\"id2\"></span><h3>Utilisateurs personnalisés et formulaires d’authentification intégrés<a class=\"heading-anchor\" href=\"#custom-users-and-the-built-in-auth-forms\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Les <a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#built-in-auth-forms\"><span class=\"std std-ref\">formulaires</span></a> et les <a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#built-in-auth-views\"><span class=\"std std-ref\">vues</span></a> intégrés de Django ont certaines attentes à propos du modèle utilisateur avec lequel ils fonctionnent.</p>\n<p>Les formulaires suivants sont compatibles avec toutes les sous-classes de <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></a>:</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.forms.AuthenticationForm\" title=\"django.contrib.auth.forms.AuthenticationForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AuthenticationForm</span></code></a>: utilise le champ de nom d’utilisateur indiqué par <a class=\"reference internal\" href=\"#django.contrib.auth.models.CustomUser.USERNAME_FIELD\" title=\"django.contrib.auth.models.CustomUser.USERNAME_FIELD\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">USERNAME_FIELD</span></code></a>.</p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.forms.SetPasswordForm\" title=\"django.contrib.auth.forms.SetPasswordForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">SetPasswordForm</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.forms.PasswordChangeForm\" title=\"django.contrib.auth.forms.PasswordChangeForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">PasswordChangeForm</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.forms.AdminPasswordChangeForm\" title=\"django.contrib.auth.forms.AdminPasswordChangeForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AdminPasswordChangeForm</span></code></a></p></li>\n</ul>\n<p>Les formulaires suivants ont certaines attentes à propos du modèle d’utilisateur et peuvent être utilisés tels quels si ces attentes sont remplies :</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.forms.PasswordResetForm\" title=\"django.contrib.auth.forms.PasswordResetForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">PasswordResetForm</span></code></a>: s’attend à ce que le modèle utilisateur possède un champ qui stocke l’adresse électronique de l’utilisateur et nommé selon la valeur renvoyée par <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser.get_email_field_name\" title=\"django.contrib.auth.models.AbstractBaseUser.get_email_field_name\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_email_field_name()</span></code></a> (<code class=\"docutils literal notranslate\"><span class=\"pre\">email</span></code> par défaut). Ce champ doit pouvoir être utilisé pour identifier l’utilisateur. Le formulaire compte aussi sur la présence du champ booléen <code class=\"docutils literal notranslate\"><span class=\"pre\">is_active</span></code> pour empêcher les utilisateurs inactifs de réinitialiser leur mot de passe.</p></li>\n</ul>\n<p>Pour finir, les formulaires suivants sont liés à la classe <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a> et doivent être réécrits ou étendus pour fonctionner avec un modèle d’utilisateur personnalisé :</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.forms.UserCreationForm\" title=\"django.contrib.auth.forms.UserCreationForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">UserCreationForm</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#django.contrib.auth.forms.UserChangeForm\" title=\"django.contrib.auth.forms.UserChangeForm\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">UserChangeForm</span></code></a></p></li>\n</ul>\n<p>Si votre modèle d’utilisateur personnalisé est une sous-classe de <code class=\"docutils literal notranslate\"><span class=\"pre\">AbstractUser</span></code>, vous pouvez alors étendre ces formulaires de cette façon :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">UserCreationForm</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">CustomUser</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CustomUserCreationForm</span><span class=\"p\">(</span><span class=\"n\">UserCreationForm</span><span class=\"p\">):</span>\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">(</span><span class=\"n\">UserCreationForm</span><span class=\"o\">.</span><span class=\"n\">Meta</span><span class=\"p\">):</span>\n        <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">CustomUser</span>\n        <span class=\"n\">fields</span> <span class=\"o\">=</span> <span class=\"n\">UserCreationForm</span><span class=\"o\">.</span><span class=\"n\">Meta</span><span class=\"o\">.</span><span class=\"n\">fields</span> <span class=\"o\">+</span> <span class=\"p\">(</span><span class=\"s2\">&quot;custom_field&quot;</span><span class=\"p\">,)</span>\n</code></pre></div>\n</section>\n<section id=\"custom-users-and-django-contrib-admin\">\n<h3>Utilisateurs personnalisés et  <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/admin/#module-django.contrib.admin\" title=\"django.contrib.admin: Django's admin site.\"><code class=\"xref py py-mod docutils literal notranslate\"><span class=\"pre\">django.contrib.admin</span></code></a><a class=\"heading-anchor\" href=\"#custom-users-and-django-contrib-admin\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Si vous souhaitez que votre modèle d’utilisateur personnalisé fonctionne également dans l’interface d’administration, celui-ci doit définir certains attributs et méthodes supplémentaires. Ces méthodes permettent au site d’administration de contrôler l’accès de l’utilisateur à son contenu :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">models.</span></span><span class=\"sig-name descname\"><span class=\"pre\">CustomUser</span></span></dt>\n<dd></dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.is_staff\">\n<span class=\"sig-name descname\"><span class=\"pre\">is_staff</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.is_staff\"><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\"><span class=\"pre\">True</span></code> si l’utilisateur est autorisé à accéder au site d’administration.</p>\n</dd></dl>\n\n<dl class=\"py attribute\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.is_active\">\n<span class=\"sig-name descname\"><span class=\"pre\">is_active</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.is_active\"><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\"><span class=\"pre\">True</span></code> si le compte utilisateur est actuellement actif.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\">\n<span class=\"sig-name descname\"><span class=\"pre\">has_perm(perm,</span> <span class=\"pre\">obj=None):</span></span></dt>\n<dd><p>Renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si l’utilisateur possède la permission indiquée. Si <code class=\"docutils literal notranslate\"><span class=\"pre\">obj</span></code> est transmis, la permission doit être vérifiée en relation avec une instance d’objet spécifique.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\">\n<span class=\"sig-name descname\"><span class=\"pre\">has_module_perms(app_label):</span></span></dt>\n<dd><p>Renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si l’utilisateur possède la permission d’accéder aux modèles de l’application indiquée.</p>\n</dd></dl>\n\n<p>Il sera aussi nécessaire d’inscrire le modèle d’utilisateur personnalisé à l’interface d’administration. Si votre modèle hérite de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.models.AbstractUser</span></code>, vous pouvez utiliser la classe existante de Django <code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.admin.UserAdmin</span></code>. Cependant, si votre modèle hérite de <a class=\"reference internal\" href=\"#django.contrib.auth.models.AbstractBaseUser\" title=\"django.contrib.auth.models.AbstractBaseUser\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">AbstractBaseUser</span></code></a>, vous devrez définir une classe <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelAdmin</span></code> personnalisée. Il est possible d’hériter de la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.admin.UserAdmin</span></code>, mais il faudra alors surcharger toutes les définitions qui se référent à des champs de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.models.AbstractUser</span></code> et qui ne se trouvent pas dans votre classe d’utilisateur personnalisée.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Si vous utilisez une classe <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelAdmin</span></code> personnalisée qui hérite de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.contrib.auth.admin.UserAdmin</span></code>, vous devez alors ajouter vos champs personnalisés à <code class=\"docutils literal notranslate\"><span class=\"pre\">fieldsets</span></code> (pour les champs qui doivent faire partie de l’édition des utilisateurs) et à <code class=\"docutils literal notranslate\"><span class=\"pre\">add_fieldsets</span></code> (pour les champs qui doivent faire partie de la création des utilisateurs). Par exemple</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.admin</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">UserAdmin</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">CustomUserAdmin</span><span class=\"p\">(</span><span class=\"n\">UserAdmin</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n    <span class=\"n\">fieldsets</span> <span class=\"o\">=</span> <span class=\"n\">UserAdmin</span><span class=\"o\">.</span><span class=\"n\">fieldsets</span> <span class=\"o\">+</span> <span class=\"p\">((</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;custom_field&quot;</span><span class=\"p\">]}),)</span>\n    <span class=\"n\">add_fieldsets</span> <span class=\"o\">=</span> <span class=\"n\">UserAdmin</span><span class=\"o\">.</span><span class=\"n\">add_fieldsets</span> <span class=\"o\">+</span> <span class=\"p\">((</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;custom_field&quot;</span><span class=\"p\">]}),)</span>\n</code></pre></div>\n<p>Voir <a class=\"reference internal\" href=\"#custom-users-admin-full-example\"><span class=\"std std-ref\">un exemple complet</span></a> pour plus de détails.</p>\n</aside>\n</section>\n<section id=\"custom-users-and-permissions\">\n<h3>Utilisateurs personnalisés et permissions<a class=\"heading-anchor\" href=\"#custom-users-and-permissions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Pour faciliter l’intégration du système des permissions de Django à votre propre classe d’utilisateur, Django propose <a class=\"reference internal\" href=\"#django.contrib.auth.models.PermissionsMixin\" title=\"django.contrib.auth.models.PermissionsMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">PermissionsMixin</span></code></a>. Il s’agit d’un modèle abstrait que vous pouvez ajouter à la hiérarchie de classes de votre modèle d’utilisateur et qui vous offre ainsi toutes les méthodes et les champs de base de données nécessaires pour la prise en charge du modèle des permissions de Django.</p>\n<p><a class=\"reference internal\" href=\"#django.contrib.auth.models.PermissionsMixin\" title=\"django.contrib.auth.models.PermissionsMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">PermissionsMixin</span></code></a> contient les méthodes et attributs suivants :</p>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.PermissionsMixin\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-prename descclassname\"><span class=\"pre\">models.</span></span><span class=\"sig-name descname\"><span class=\"pre\">PermissionsMixin</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.PermissionsMixin\"><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.contrib.auth.models.PermissionsMixin.is_superuser\">\n<span class=\"sig-name descname\"><span class=\"pre\">is_superuser</span></span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.PermissionsMixin.is_superuser\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Valeur booléenne. Indique que cet utilisateur possède toutes les permissions sans avoir besoin de les lui attribuer explicitement.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.PermissionsMixin.get_user_permissions\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_user_permissions</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.PermissionsMixin.get_user_permissions\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie l’ensemble des permissions (chaînes) que l’utilisateur obtient directement.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">obj</span></code> est transmis, ne renvoie que les permissions d’utilisateur liées à cet objet spécifique.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.PermissionsMixin.get_group_permissions\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_group_permissions</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.PermissionsMixin.get_group_permissions\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie l’ensemble des permissions (chaînes) que l’utilisateur obtient au travers des groupes auxquels il/elle appartient.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">obj</span></code> est transmis, ne renvoie que les permissions de groupe liées à cet objet spécifique.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.PermissionsMixin.get_all_permissions\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_all_permissions</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.PermissionsMixin.get_all_permissions\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><p>Renvoie l’ensemble des permissions (chaînes) que l’utilisateur obtient directement ou au travers des groupes auxquels il appartient.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">obj</span></code> est transmis, ne renvoie que les permissions liées à cet objet spécifique.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.PermissionsMixin.has_perm\">\n<span class=\"sig-name descname\"><span class=\"pre\">has_perm</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">perm</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.PermissionsMixin.has_perm\"><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\"><span class=\"pre\">True</span></code> si l’utilisateur possède la permission indiquée, où <code class=\"docutils literal notranslate\"><span class=\"pre\">perm</span></code> est au format <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;&lt;étiquette</span> <span class=\"pre\">application&gt;.&lt;code</span> <span class=\"pre\">permission&gt;&quot;</span></code> (voir <a class=\"reference internal\" href=\"/fr/5.1/topics/auth/default/#topic-authorization\"><span class=\"std std-ref\">permissions</span></a>). Si <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active\" title=\"django.contrib.auth.models.User.is_active\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">User.is_active</span></code></a> et <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser\" title=\"django.contrib.auth.models.User.is_superuser\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">is_superuser</span></code></a> sont tous deux à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, cette méthode renvoie toujours <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">obj</span></code> est transmis, cette méthode ne contrôle pas la permission au niveau du modèle, mais pour l’objet indiqué.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.PermissionsMixin.has_perms\">\n<span class=\"sig-name descname\"><span class=\"pre\">has_perms</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">perm_list</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">obj</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.PermissionsMixin.has_perms\"><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\"><span class=\"pre\">True</span></code> si l’utilisateur possède toutes les permissions indiquées, où chaque permission est au format <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;&lt;étiquette</span> <span class=\"pre\">application&gt;.&lt;code</span> <span class=\"pre\">permission&gt;&quot;</span></code>. Si <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active\" title=\"django.contrib.auth.models.User.is_active\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">User.is_active</span></code></a> et <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser\" title=\"django.contrib.auth.models.User.is_superuser\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">is_superuser</span></code></a> sont tous deux à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, cette méthode renvoie toujours <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>.</p>\n<p>Si <code class=\"docutils literal notranslate\"><span class=\"pre\">obj</span></code> est transmis, cette méthode ne contrôle pas les permissions au niveau du modèle, mais pour l’objet indiqué.</p>\n</dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.contrib.auth.models.PermissionsMixin.has_module_perms\">\n<span class=\"sig-name descname\"><span class=\"pre\">has_module_perms</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">package_name</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.contrib.auth.models.PermissionsMixin.has_module_perms\"><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\"><span class=\"pre\">True</span></code> si l’utilisateur possède au moins une permission dans le paquet donné (l’étiquette d’application Django). Si <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active\" title=\"django.contrib.auth.models.User.is_active\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">User.is_active</span></code></a> et <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser\" title=\"django.contrib.auth.models.User.is_superuser\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">is_superuser</span></code></a> sont tous deux à <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>, cette méthode renvoie toujours <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code>.</p>\n</dd></dl>\n\n</dd></dl>\n\n<aside class=\"admonition-permissionsmixin-and-modelbackend admonition\">\n<p class=\"admonition-title\"><code class=\"docutils literal notranslate\"><span class=\"pre\">PermissionsMixin</span></code> et <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelBackend</span></code></p>\n<p>Si vous n’intégrez pas <a class=\"reference internal\" href=\"#django.contrib.auth.models.PermissionsMixin\" title=\"django.contrib.auth.models.PermissionsMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">PermissionsMixin</span></code></a> vous devez vous assurer de ne pas appeler les méthodes de permissions sur <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelBackend</span></code>. <code class=\"docutils literal notranslate\"><span class=\"pre\">ModelBackend</span></code> s’attend à ce que certains champs soient disponibles dans votre modèle d’utilisateur. Si ce dernier ne fournit pas ces champs, vous obtiendrez des erreurs de base de données lorsque vous contrôlez les permissions.</p>\n</aside>\n</section>\n<section id=\"custom-users-and-proxy-models\">\n<h3>Utilisateurs personnalisés et modèles mandataires<a class=\"heading-anchor\" href=\"#custom-users-and-proxy-models\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Une limite connue des modèles d’utilisateur personnalisés est que leur installation casse tout modèle mandataire étendant le modèle <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a>. Les modèles mandataires doivent hériter d’une classe de base concrète ; en définissant un modèle d’utilisateur personnalisé, vous supprimez la capacité de Django à identifier de manière fiable la classe de base.</p>\n<p>Si votre projet utilise des modèles mandataires, vous devez soit modifier ces modèles afin qu’ils étendent le modèle d’utilisateur utilisé dans votre projet, soit fusionner le comportement du modèle mandataire dans votre sous-classe de <a class=\"reference internal\" href=\"/fr/5.1/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">User</span></code></a>.</p>\n</section>\n<section id=\"a-full-example\">\n<span id=\"custom-users-admin-full-example\"></span><h3>Un exemple complet<a class=\"heading-anchor\" href=\"#a-full-example\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Voici un exemple d’application d’utilisateur personnalisé compatible avec l’interface d’administration. Ce modèle d’utilisateur utilise une adresse électronique comme nom d’utilisateur et possède un champ date de naissance obligatoire ; il ne fournit aucun contrôle de permission, excepté un drapeau <code class=\"docutils literal notranslate\"><span class=\"pre\">admin</span></code> sur le compte utilisateur. Ce modèle est compatible avec tous les formulaires et les vues d’authentification intégrés, à l’exception des formulaires de création d’utilisateur. Cet exemple illustre la façon dont la plupart des composants interagissent, mais il ne s’agit pas de code pouvant être directement copié dans des projets en production.</p>\n<p>Ce code pourrait être entièrement placé dans un fichier <code class=\"docutils literal notranslate\"><span class=\"pre\">models.py</span></code> d’une application d’authentification personnalisé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=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">BaseUserManager</span><span class=\"p\">,</span> <span class=\"n\">AbstractBaseUser</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyUserManager</span><span class=\"p\">(</span><span class=\"n\">BaseUserManager</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">create_user</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">email</span><span class=\"p\">,</span> <span class=\"n\">date_of_birth</span><span class=\"p\">,</span> <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Creates and saves a User with the given email, date of</span>\n<span class=\"sd\">        birth and password.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">email</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Users must have an email address&quot;</span><span class=\"p\">)</span>\n\n        <span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">model</span><span class=\"p\">(</span>\n            <span class=\"n\">email</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">normalize_email</span><span class=\"p\">(</span><span class=\"n\">email</span><span class=\"p\">),</span>\n            <span class=\"n\">date_of_birth</span><span class=\"o\">=</span><span class=\"n\">date_of_birth</span><span class=\"p\">,</span>\n        <span class=\"p\">)</span>\n\n        <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">set_password</span><span class=\"p\">(</span><span class=\"n\">password</span><span class=\"p\">)</span>\n        <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_db</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">user</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">create_superuser</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">email</span><span class=\"p\">,</span> <span class=\"n\">date_of_birth</span><span class=\"p\">,</span> <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n<span class=\"w\">        </span><span class=\"sd\">&quot;&quot;&quot;</span>\n<span class=\"sd\">        Creates and saves a superuser with the given email, date of</span>\n<span class=\"sd\">        birth and password.</span>\n<span class=\"sd\">        &quot;&quot;&quot;</span>\n        <span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">create_user</span><span class=\"p\">(</span>\n            <span class=\"n\">email</span><span class=\"p\">,</span>\n            <span class=\"n\">password</span><span class=\"o\">=</span><span class=\"n\">password</span><span class=\"p\">,</span>\n            <span class=\"n\">date_of_birth</span><span class=\"o\">=</span><span class=\"n\">date_of_birth</span><span class=\"p\">,</span>\n        <span class=\"p\">)</span>\n        <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">is_admin</span> <span class=\"o\">=</span> <span class=\"kc\">True</span>\n        <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">_db</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">user</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyUser</span><span class=\"p\">(</span><span class=\"n\">AbstractBaseUser</span><span class=\"p\">):</span>\n    <span class=\"n\">email</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">EmailField</span><span class=\"p\">(</span>\n        <span class=\"n\">verbose_name</span><span class=\"o\">=</span><span class=\"s2\">&quot;email address&quot;</span><span class=\"p\">,</span>\n        <span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">255</span><span class=\"p\">,</span>\n        <span class=\"n\">unique</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span>\n    <span class=\"p\">)</span>\n    <span class=\"n\">date_of_birth</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n    <span class=\"n\">is_active</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">BooleanField</span><span class=\"p\">(</span><span class=\"n\">default</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n    <span class=\"n\">is_admin</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">BooleanField</span><span class=\"p\">(</span><span class=\"n\">default</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n\n    <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"n\">MyUserManager</span><span class=\"p\">()</span>\n\n    <span class=\"n\">USERNAME_FIELD</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;email&quot;</span>\n    <span class=\"n\">REQUIRED_FIELDS</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;date_of_birth&quot;</span><span class=\"p\">]</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__str__</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><span class=\"n\">email</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">has_perm</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">perm</span><span class=\"p\">,</span> <span class=\"n\">obj</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"s2\">&quot;Does the user have a specific permission?&quot;</span>\n        <span class=\"c1\"># Simplest possible answer: Yes, always</span>\n        <span class=\"k\">return</span> <span class=\"kc\">True</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">has_module_perms</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">app_label</span><span class=\"p\">):</span>\n        <span class=\"s2\">&quot;Does the user have permissions to view the app `app_label`?&quot;</span>\n        <span class=\"c1\"># Simplest possible answer: Yes, always</span>\n        <span class=\"k\">return</span> <span class=\"kc\">True</span>\n\n    <span class=\"nd\">@property</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">is_staff</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"s2\">&quot;Is the user a member of staff?&quot;</span>\n        <span class=\"c1\"># Simplest possible answer: All admins are staff</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">is_admin</span>\n</code></pre></div>\n<p>Puis, pour inscrire ce modèle d’utilisateur personnalisé dans l’administration de Django, le code suivant doit se trouver dans le fichier <code class=\"docutils literal notranslate\"><span class=\"pre\">admin.py</span></code> de l’application :</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">forms</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">admin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Group</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.admin</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">UserAdmin</span> <span class=\"k\">as</span> <span class=\"n\">BaseUserAdmin</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.contrib.auth.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ReadOnlyPasswordHashField</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.exceptions</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ValidationError</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">customauth.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">MyUser</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">UserCreationForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">ModelForm</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;A form for creating new users. Includes all the required</span>\n<span class=\"sd\">    fields, plus a repeated password.&quot;&quot;&quot;</span>\n\n    <span class=\"n\">password1</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">label</span><span class=\"o\">=</span><span class=\"s2\">&quot;Password&quot;</span><span class=\"p\">,</span> <span class=\"n\">widget</span><span class=\"o\">=</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">PasswordInput</span><span class=\"p\">)</span>\n    <span class=\"n\">password2</span> <span class=\"o\">=</span> <span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span>\n        <span class=\"n\">label</span><span class=\"o\">=</span><span class=\"s2\">&quot;Password confirmation&quot;</span><span class=\"p\">,</span> <span class=\"n\">widget</span><span class=\"o\">=</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">PasswordInput</span>\n    <span class=\"p\">)</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">MyUser</span>\n        <span class=\"n\">fields</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;email&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;date_of_birth&quot;</span><span class=\"p\">]</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">clean_password2</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Check that the two password entries match</span>\n        <span class=\"n\">password1</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s2\">&quot;password1&quot;</span><span class=\"p\">)</span>\n        <span class=\"n\">password2</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"s2\">&quot;password2&quot;</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">password1</span> <span class=\"ow\">and</span> <span class=\"n\">password2</span> <span class=\"ow\">and</span> <span class=\"n\">password1</span> <span class=\"o\">!=</span> <span class=\"n\">password2</span><span class=\"p\">:</span>\n            <span class=\"k\">raise</span> <span class=\"n\">ValidationError</span><span class=\"p\">(</span><span class=\"s2\">&quot;Passwords don&#39;t match&quot;</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">password2</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">save</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">commit</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Save the provided password in hashed format</span>\n        <span class=\"n\">user</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">(</span><span class=\"n\">commit</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n        <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">set_password</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cleaned_data</span><span class=\"p\">[</span><span class=\"s2\">&quot;password1&quot;</span><span class=\"p\">])</span>\n        <span class=\"k\">if</span> <span class=\"n\">commit</span><span class=\"p\">:</span>\n            <span class=\"n\">user</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">user</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">UserChangeForm</span><span class=\"p\">(</span><span class=\"n\">forms</span><span class=\"o\">.</span><span class=\"n\">ModelForm</span><span class=\"p\">):</span>\n<span class=\"w\">    </span><span class=\"sd\">&quot;&quot;&quot;A form for updating users. Includes all the fields on</span>\n<span class=\"sd\">    the user, but replaces the password field with admin&#39;s</span>\n<span class=\"sd\">    disabled password hash display field.</span>\n<span class=\"sd\">    &quot;&quot;&quot;</span>\n\n    <span class=\"n\">password</span> <span class=\"o\">=</span> <span class=\"n\">ReadOnlyPasswordHashField</span><span class=\"p\">()</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">MyUser</span>\n        <span class=\"n\">fields</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;email&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;password&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;date_of_birth&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;is_active&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;is_admin&quot;</span><span class=\"p\">]</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">UserAdmin</span><span class=\"p\">(</span><span class=\"n\">BaseUserAdmin</span><span class=\"p\">):</span>\n    <span class=\"c1\"># The forms to add and change user instances</span>\n    <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"n\">UserChangeForm</span>\n    <span class=\"n\">add_form</span> <span class=\"o\">=</span> <span class=\"n\">UserCreationForm</span>\n\n    <span class=\"c1\"># The fields to be used in displaying the User model.</span>\n    <span class=\"c1\"># These override the definitions on the base UserAdmin</span>\n    <span class=\"c1\"># that reference specific fields on auth.User.</span>\n    <span class=\"n\">list_display</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;email&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;date_of_birth&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;is_admin&quot;</span><span class=\"p\">]</span>\n    <span class=\"n\">list_filter</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;is_admin&quot;</span><span class=\"p\">]</span>\n    <span class=\"n\">fieldsets</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span><span class=\"kc\">None</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;email&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;password&quot;</span><span class=\"p\">]}),</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;Personal info&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;date_of_birth&quot;</span><span class=\"p\">]}),</span>\n        <span class=\"p\">(</span><span class=\"s2\">&quot;Permissions&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;is_admin&quot;</span><span class=\"p\">]}),</span>\n    <span class=\"p\">]</span>\n    <span class=\"c1\"># add_fieldsets is not a standard ModelAdmin attribute. UserAdmin</span>\n    <span class=\"c1\"># overrides get_fieldsets to use this attribute when creating a user.</span>\n    <span class=\"n\">add_fieldsets</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n        <span class=\"p\">(</span>\n            <span class=\"kc\">None</span><span class=\"p\">,</span>\n            <span class=\"p\">{</span>\n                <span class=\"s2\">&quot;classes&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;wide&quot;</span><span class=\"p\">],</span>\n                <span class=\"s2\">&quot;fields&quot;</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"s2\">&quot;email&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;date_of_birth&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;password1&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;password2&quot;</span><span class=\"p\">],</span>\n            <span class=\"p\">},</span>\n        <span class=\"p\">),</span>\n    <span class=\"p\">]</span>\n    <span class=\"n\">search_fields</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;email&quot;</span><span class=\"p\">]</span>\n    <span class=\"n\">ordering</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;email&quot;</span><span class=\"p\">]</span>\n    <span class=\"n\">filter_horizontal</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n\n<span class=\"c1\"># Now register the new UserAdmin...</span>\n<span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">site</span><span class=\"o\">.</span><span class=\"n\">register</span><span class=\"p\">(</span><span class=\"n\">MyUser</span><span class=\"p\">,</span> <span class=\"n\">UserAdmin</span><span class=\"p\">)</span>\n<span class=\"c1\"># ... and, since we&#39;re not using Django&#39;s built-in permissions,</span>\n<span class=\"c1\"># unregister the Group model from admin.</span>\n<span class=\"n\">admin</span><span class=\"o\">.</span><span class=\"n\">site</span><span class=\"o\">.</span><span class=\"n\">unregister</span><span class=\"p\">(</span><span class=\"n\">Group</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Finalement, définissez le modèle personnalisé comme modèle d’utilisateur par défaut dans votre projet au moyen du réglage <a class=\"reference internal\" href=\"/fr/5.1/ref/settings/#std-setting-AUTH_USER_MODEL\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">AUTH_USER_MODEL</span></code></a> dans votre fichier <code class=\"docutils literal notranslate\"><span class=\"pre\">settings.py</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">AUTH_USER_MODEL</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;customauth.MyUser&quot;</span>\n</code></pre></div>\n</section>\n</section>","rootId":"customizing-authentication-in-django","toc":[{"title":"Autres sources d’authentification","anchor":"other-authentication-sources","children":[{"title":"Définition de moteurs d’authentification","anchor":"specifying-authentication-backends","children":[]},{"title":"Écriture d’un moteur d’authentification","anchor":"writing-an-authentication-backend","children":[]},{"title":"Gestion des autorisations dans les moteurs personnalisés","anchor":"handling-authorization-in-custom-backends","children":[{"title":"Autorisation pour les utilisateurs anonymes","anchor":"authorization-for-anonymous-users","children":[]},{"title":"Autorisation pour les utilisateurs inactifs","anchor":"authorization-for-inactive-users","children":[]},{"title":"Gestion des permissions sur les objets","anchor":"handling-object-permissions","children":[]}]}]},{"title":"Permissions personnalisées","anchor":"custom-permissions","children":[]},{"title":"Extension du modèle User existant","anchor":"extending-the-existing-user-model","children":[]},{"title":"Substitution par un modèle User personnalisé","anchor":"substituting-a-custom-user-model","children":[{"title":"Utilisation d’un modèle d’utilisateur personnalisé au départ d’un projet","anchor":"using-a-custom-user-model-when-starting-a-project","children":[]},{"title":"Conversion vers un modèle d’utilisateur personnalisé en cours de projet","anchor":"changing-to-a-custom-user-model-mid-project","children":[]},{"title":"Applications réutilisables et AUTH_USER_MODEL","anchor":"reusable-apps-and-auth-user-model","children":[]},{"title":"Références au modèle User","anchor":"referencing-the-user-model","children":[]},{"title":"Indication d’une modèle d’utilisateur personnalisé","anchor":"specifying-a-custom-user-model","children":[]},{"title":"Écriture d’un gestionnaire pour un modèle d’utilisateur personnalisé","anchor":"writing-a-manager-for-a-custom-user-model","children":[]},{"title":"Extension du modèle User par défaut de Django","anchor":"extending-django-s-default-user","children":[]},{"title":"Utilisateurs personnalisés et formulaires d’authentification intégrés","anchor":"custom-users-and-the-built-in-auth-forms","children":[]},{"title":"Utilisateurs personnalisés et  django.contrib.admin","anchor":"custom-users-and-django-contrib-admin","children":[]},{"title":"Utilisateurs personnalisés et permissions","anchor":"custom-users-and-permissions","children":[]},{"title":"Utilisateurs personnalisés et modèles mandataires","anchor":"custom-users-and-proxy-models","children":[]},{"title":"Un exemple complet","anchor":"a-full-example","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/5.1/topics/"},{"docname":"topics/auth/index","title":"Authentification des utilisateurs dans Django","url":"/fr/5.1/topics/auth/"}],"prev":{"docname":"topics/auth/passwords","title":"Gestion des mots de passe dans Django","url":"/fr/5.1/topics/auth/passwords/"},"next":{"docname":"topics/cache","title":"L’infrastructure de cache dans Django","url":"/fr/5.1/topics/cache/"},"formats":{"html":"/fr/5.1/topics/auth/customizing/","markdown":"/fr/5.1/topics/auth/customizing.md","json":"/fr/5.1/topics/auth/customizing.json"},"source":"https://github.com/django/django/blob/stable/5.1.x/docs/topics/auth/customizing.txt","official":"https://docs.djangoproject.com/fr/5.1/topics/auth/customizing/","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","it","pt-br","ko","es","el","pl"]}