0

Je développe un système de base de données scolaire dans Django 1.5, et prévoyais avoir un certain nombre de types d'utilisateurs différents (Student, Staff, Parent) qui sous-classe AbstractUser (en fait, un autre résumé sous-classe de AbstractUser). J'essayais juste d'ajouter une application développée en externe à mon système, qui utilise User dans un ForeignKey pour certains de ses modèles, mais cela échoue car mon type d'utilisateur n'est pas une instance 'User'. Je ne peux pas configurer les modèles d'applications pour utiliser AbstractUser car on ne peut pas utiliser de classes abstraites pour les clés étrangères. J'envisageais alors d'ajouter à mes settings.py AUTH_USER_MODEL = 'myapp.MyUser' et en utilisant settings.AUTH_USER_MODEL au lieu de User pour ForeignKey dans l'application. Cependant, j'ai 3 types d'utilisateurs différents, donc je ne peux pas le faire non plus. Un prototype antérieur utilisé Django 1.4, qui ne prenait pas en charge les modèles utilisateur personnalisés, avait donc une référence à un utilisateur, mais cela nécessitait une jointure supplémentaire pour chaque requête, ce qui conduisait à des requêtes assez complexes. Est-ce la seule façon d'aller de l'avant, ou existe-t-il une autre solution?Sous-classe AbstractUser dans Django pour deux types d'utilisateurs

Répondre

3

Je l'ai utilisé avec succès la solution suivante:
1. Créez SchoolUser classe models.py - ce sera votre AUTH_USER_MODEL classe

TYPES = (('Student', 'Student'), ('Staff', 'Staff'), ('Parent', 'Parent'),) 
class SchoolUser(AbstractUser): 
    type = models.CharField(max_length=10, choices=TYPES, default='Student') 

2. Créer un fichier users.py et y mettre toute la logique des utilisateurs . Avoir une classe abstraite que tous les autres héritent de et qui mettra en œuvre la méthode de création:

class UserManager(object): 
    def __init__(self, user): 
     self.user = user 

    @classmethod 
    def factory(cls, user): 
     """ 
     Dynamically creates user object 
     """ 
     if cls.__name__.startswith(user.type): # Children class naming convention is important 
      return cls(user) 
     for sub_cls in cls.__subclasses__(): 
      result = sub_cls.factory(user) 
      if result is not None: 
       return result 

classes enfants exemples (aller aussi fichier users.py):

class StudentUser(UserManager): 
    def do_something(self): 
     pass 
class StaffUser(UserManager): 
    def do_something(self): 
     pass 
class ParentUser(UserManager): 
    def do_something(self): 
     pass 

Views est où la magie se produit ;)

def my_view(request): 
    school_user = UserManager.factory(request.user) 
    if school_user.do_something: # each class can have different behaviour 

de cette façon, vous n'avez pas besoin de savoir, quel type d'utilisateur, il est, tout mettre en œuvre votre logique.
J'espère que c'est assez clair, sinon laissez-moi savoir!

Questions connexes