Je travaille sur un projet à Django qui appelle à avoir des groupes d'utilisateurs distincts dans leur propre nom d'utilisateur code> nom d'utilisateur code>. p>
Ainsi, par exemple, je pourrais avoir plusieurs "organisations", et Je sais que je peux le faire en utilisant un autre modèle contenant un identifiant de nom d'utilisateur / organisation, mais qui laisse toujours ce champ inutile (et requis) sur le défaute Django auth J'ai déjà écrit par son propre backend qui authentifie un utilisateur contre LDAP. Cependant, comme je l'ai déjà mentionné, je suis toujours coincé avec le problème de la possibilité de remplir / ignorer le champ code> nom d'utilisateur code> sur l'utilisateur Django par défaut. P>
existe-t-il un moyen de supprimer la contrainte d'unicité du nom d'utilisateur code> pour les utilisateurs de Django Auth? P> nom d'utilisateur code> ne doit avoir qu'à être unique dans cette organisation. P>
utilisateur code> que je devrais peupler avec quelque chose. P>
5 Réponses :
Je ne suis pas sûr que ce soit exactement ce que vous recherchez, mais je pense que vous pouvez utiliser un hack similaire à ce qui est dans Cette réponse .
Le code suivant fonctionne, tant que c'est dans un endroit où est exécuté lorsque Django charge vos modèles. p> Notez que cela ne modifiera pas la contrainte unique de la base de données sur la table auth_user code> si elle a déjà été été créé. Par conséquent, vous devez faire ce changement
Je ne suis pas sûr que ça va travailler. L'attribut unique code> est propagé à la base de données comme une contrainte sur ce champ. Une fois que cela est fait, modifier Django Meta Info Info ne va pas aider. Si vous n'allez jamais réellement utiliser i> (c'est-à-dire afficher / modifier) le nom d'utilisateur, alors quelque chose pour le rendre unique suffira. Par exemple. Ce que DRBLOODMoney suggère.
Ceci fait i> travaille (je l'ai essayé), mais puisqu'il accède à _méta code>, il s'appuie sur la mise en œuvre interne et non l'interface documentée, donc je me méfie de l'utiliser. +1 cependant, ça marche.
Eh bien, cela fonctionne sur des contraintes non nulles (j'ai essayé cela), donc je ne vois pas pourquoi pas. Tant que "myusermodel" est une classe qui hérite de "Auth.User" et la ligne est placée tout droit après le modèle, cela semble fonctionner. C'est juste que c'est un hack légèrement laid.
Cela fonctionne réellement bien sans sous-classement auth.user code>. Vous pouvez simplement faire user._meta.get_field ('Nom d'utilisateur'). Unique = FALSE code>. Cela fonctionne, tant qu'il existe dans un fichier chargé lorsque Django charge vos modèles. J'accepte cette réponse, puisqu'elle est fonctionnelle, mais je me sens toujours comme si ce n'est pas une très bonne solution, car il peut se casser avec des mises à jour de Django (il s'appuie sur une fonctionnalité interne non documentée).
Si cela fonctionne, j'ai besoin de quelqu'un pour m'expliquer. Il y a (au moins) 2 problèmes: 1) Le champ est _unique code>, pas unique code>. (Au moins dans 1.1.1 Ceci est vrai. Dans 0.97Pre, c'était unique code>.) 2) Quel que soit le nom, définir le champ _unique code> ne change pas à la < I> Database Contrainte forcée I> que le champ est unique i>, une contrainte créée à l'heure Syncdb et qui ne disparaît pas en définissant ce champ. J'attends l'illumination. Vraiment, je fais.
@TM oh, c'est intéressant ... Je ne pensais pas que cela fonctionnerait sur le modèle d'utilisateur d'origine, mais c'est bon de savoir ... Ouais, si vous trouvez un moyen de faire ce genre de chose sans recourir à des hacks laids , Je m'intéresse aussi!
@Peter Rowell je ne sais pas environ 1), mais en ce qui concerne 2) Maintenant que j'ai commencé à réfléchir à la question et à TM a dit que cela fonctionne dans plus de contextes que je ne le pensais, je suppose que Django doit connaître tous les Modèles du projet avant d'exécuter la table Create SQL car ils doivent être exécutés dans le bon ordre (touches étrangères). Par conséquent, je suppose que les métadonnées sont encore possibles de changer même après la déclaration de modèle car la SQL n'est formée que lorsque tous les modèles ne sont déclarés ... Juste une suppose cependant.
@Peterrowell, oui vous êtes correct, il doit être _unique code> pas unique. Mon erreur. Malheureusement, je ne peux plus éditer ce commentaire. Quant à la question n ° 2: vous devez faire ce changement avant i> vous exécutez Syncdb pour créer la table auth_user. Si vous faites cela, la contrainte de la base de données ne sera pas créée. Sinon, si vous avez déjà exécuté Syncdb, vous pouvez modifier la table manuellement. @MONIKA, ce serait bien si vous pouviez mettre à jour votre réponse à utiliser _unique code> et faire la modification directement sur utilisateur code>.
Parfois, j'oublie que je peux éditer les autres peuples réponses moi-même ... J'ai mis à jour cette réponse pour le rendre plus précis / clair, afin de répondre aux préoccupations des péterrowells.
Je n'ai pas personnellement été tenu de trouver une solution à cela, mais d'une façon de s'attaquer à cela (d'une perspective SaaS) aurait pour préfixer le nom d'utilisateur avec un identifiant organisationnel (présumer des organisations uniques). Par exemple: sous-domaine.Votresière.com équivaut à un utilisateur avec le nom d'utilisateur: sous-domaines_Ausername. Il vous suffirait de coder une logique commerciale sur la connexion à un sous-domaine pour classer cela sur le nom d'utilisateur. P>
Oui, cela fonctionne et j'ai envisagé, mais le nom d'utilisateur n'est déjà que de 30 caractères et l'ajout du préfixe réduit rapidement la taille à quelque chose inutilisable.
Ce que vous pouvez faire est d'étendre le modèle utilisateur. Pour la table utilisateur, génère un nom d'utilisateur (par exemple A_123, A_345) qui ne sera pas affiché du tout sur le site.
Créez ensuite un nouveau modèle qui étend l'utilisateur. P>
class AppUser(User):
username = models.CharField...
organization = models.CharField...
Je suis confronté au même problème et je lis beaucoup (sur la façon de résoudre ce problème dans 1.5) et je pensais juste à une solution beaucoup plus simple. Et si vous ajoutez simplement un préfixe de longueur fixe avec l'ID d'organisation pour stocker le nom d'utilisateur? p>
I.e. Organisation ID = 115, nom d'utilisateur choisi = "John" et une longueur fixe de 6. Donc, dans la base de données que vous stockez en tant que nom d'utilisateur "000115_John". P>
Lorsque vous effectuez la connexion, vous viennent de rejoindre les deux paramètres et essayez d'authentifier avec ce que Django fournit. Je ne sais pas si la longueur fixe est strictement nécessaire mais que vous pourrez éviter des résultats indésirables si un utilisateur choisit un nom d'utilisateur avec uniquement des chiffres. P>
Si vous voulez des réponses, postez ceci comme une question.
J'ai également souffert de ce problème. Je faisais un projet où je devais utiliser le courrier électronique et le mobile no. En tant que champs de connexion, mais aucun d'entre eux ne doit être unique parce que leurs types d'utilisateurs étaient différents et qu'un utilisateur peut avoir plus d'une entité utilisateur et que le projet ne nécessitait que une seule table utilisateur authentifiant (Droite hectique!).
donc j'ai prolongé abstractbaseuser classe où je pourrais changer l'attribut nom_serveur_field. Voici comment: - p> oui exactement, surpris? UserName_field devrait être un domaine unique qui est la contrainte de cet attribut. Je ne pouvais pas utiliser e-mail ou mobile no. comme champ unique. p> Puis j'ai créé un gestionnaire personnalisé pour supprimer le champ Nom d'utilisateur (référence = https://simpleisbetterthancomplef.com/Tutorial/2016/07/22/how-to-extend-django-user-model.html#abstractBaseUser ) p> Cela fera le tour. p> p>
Avez-vous trouvé des effets secondaires de cela? Est-ce que UserName_field a réellement utilisé par l'un des modules Django ou DRF sous-jacents? (Je n'ai pas cherché de manière exhaustive pour cela ..)