Nous exécutons plusieurs sites django (appelons-les site1, site2, site3) par rapport à la même base de données, et nous souhaitons autoriser les noms d'utilisateurs en double. Le site et le cadre d'authentification ne semblent pas réaliser cela, par défaut, le nom d'utilisateur est un champ unique dans auth.User.Plusieurs sites et utilisateurs
Donc ce que je l'ai fait jusqu'à présent (patch singe, déconner avec l'objet utilisateur ...):
User._meta.get_field('username')._unique = False
User.add_to_class('site', models.ForeignKey(Site, default=Site.objects.get_current().id, blank=True, null=True))
User._meta.unique_together = (('username', 'site'),)
Cette pièce supprime l'unicité du nom d'utilisateur, ajouter un champ de site, faire le couple (nom d'utilisateur, site) unique.
Puis viennent les problèmes qui pourraient survenir lors de la demande d'un User.objects.get (username = xx) (par exemple, backends d'authentification), si certains utilisateurs ont le même nom d'utilisateur sur un site différent. Donc, j'ai décidé de patcher le gestionnaire User.objects:
def get_query_set(filter=True):
q = QuerySet(User.objects.model, using=User.objects._db)
if filter:
return q.filter(site = Site.objects.get_current())
return q
User.objects.get_query_set = get_query_set
semble fonctionner jusqu'à présent. Mais ... les sites utilisent à peu près les mêmes objets, et il est probable que nous changions le champ utilisateur de ces objets en utilisant l'interface d'administration, qui est commune à tous les sites ... donc, si je veux attribuer un objet (qui a une clé étrangère à auh.User) à un utilisateur de site2 tout en étant connecté en tant qu'administrateur sur site1, cela ne fonctionnera pas, car le gestionnaire d'utilisateurs filtrera sur site = site1.
Je creusa un peu, a constaté que cela semble fonctionner:
class UserDefaultManager(UserManager):
def get_query_set(self, filter=None):
return QuerySet(User.objects.model)
User._default_manager = UserDefaultManager()
Pour autant que je comprends, _default_manager est utilisé par le gestionnaire des objets connexes. Ensuite, le filtre User.objects.get (username = xx) sur les sites, et an_object.user ne le fera pas. Eh bien, la question est: oui, c'est désordonné, et je suis sûr qu'il y aura des défauts, mais lesquels sont-ils?
La question suivante est: si elle est valide, alors quel est le meilleur endroit pour mettre cette partie du code? Il est actuellement dans un fichier models.py, juste couru que le module est chargé ...
Ne serait-il pas plus simple de stocker les sites pour lesquels un nom d'utilisateur est valide et de vérifier cette liste lors de l'authentification? De cette façon, vous pouvez offrir à un utilisateur commençant sur un site différent qui utilise déjà la possibilité de réutiliser son identifiant, comme le fait Stack Exchange. –
D'autres méthodes seraient plus simples et moins __messy__ mais si vous voulez vraiment utiliser celui-ci, alors vous devriez créer un fichier __manager.py__ – BlueMagma
Cette question vous donne-t-elle des idées? http://stackoverflow.com/questions/4662348/implementing-single-sign-on-sso-using-django – Pramod