2010-11-30 38 views
0

Je voudrais étendre le modèle User, donc je peux mettre des champs et des fonctions supplémentaires (pas seulement les champs, gardez à l'esprit, ou bien (enfin, encore) je pourrais utiliser get_profile(), ce que je trouve moche).Etendre le modèle Django User (le faire fonctionner dans request.user), Django 1.2.3

Aussi je voudrais utiliser ce nouveau modèle étendu de l'utilisateur dans request.user, comme ceci:

modèle d'utilisation étendu:

# imports etc 

class CustomUser(User): 
    extra_field = ... 

    def extra_function(self): 
     ... 

     return ... 

vue Exemple d'utilisation:

# imports etc 

def extra_function_view(request): 
    print request.user.username 
    print request.user.extra_field 

    request.user.extra_function() 

    return HttpResponse(...) 

Le Le code ci-dessus ne fonctionne évidemment pas, car extra_field et extra_function ne sont pas dans le modèle User.

Maintenant, j'ai trouvé une méthode pour y parvenir, en utilisant un backend d'authentification, qui est assez complexe, et que je n'ai pas pu utiliser dans Django 1.2.3.

AUTHENTICATION_BACKENDS = (
    'myproject.auth_backends.CustomUserModelBackend', 
) 
... 

CUSTOM_USER_MODEL = 'accounts.CustomUser' 

En outre plus essayé d'autres méthodes, comme l'utilisation de signaux, qui ne fonctionnait pas. Pour moi, la seule solution semble être d'ajuster le modèle User au sein de Django (ce qui n'est pas une solution élégante, en ajustant le code source de Django, mais c'est une solution soignée au niveau du code).

Donc, je cherche une solution pour cela .. a-t-on déjà fait ça?

Merci pour l'instant

Stefan

Répondre

2

Vous êtes sur la bonne voie avec réglage de l'authentification backend.

Les backends d'authentification peuvent être assez simples, voici un petit snip que nous utilisons dans notre projet.

class LocalAccount(object): 
    def authenticate(self, system=None, username=None, password=None): 
     try: 
      user = User.objects.get(system=system, alias=username) 
      if user.check_password(password): 
       return user 
     except User.DoesNotExist: 
      return None 

    def get_user(self, user_id): 
     'returns user' 

    def get_all_permissions(self, user_obj): 
     'returns user permissions' 

    def has_perm(self, user_obj, perm): 
     'verifies permission, remember you can hardcode these' 

    def get_group_permissions(self, user_obj): 
     return set() #We don't use this 

    def has_module_perms(self, user_obj, app_label): 
     return False 

Ceci vous permet de renvoyer le modèle d'utilisateur que vous souhaitez retourner. Tant que votre modèle d'utilisateur est fondamentalement similaire au modèle utilisateur de Django, vous ne rencontrerez aucun problème. Gardez également à l'esprit que l'extension de l'utilisateur et l'inclusion de l'application entraîneront l'héritage du modèle dans le modèle utilisateur Django et dans votre propre modèle utilisateur. Votre meilleure option est de copier le modèle d'utilisateur Django et de le modifier. Pour notre projet, nous n'incluons même pas 'auth' dans les paramètres des applications installées.

Le concept ici est Python duck typing. Tant que le modèle d'utilisateur que vous créez a la même interface que celle recherchée par Django (méthodes, champs), peu importe que ce soit la classe User spécifiée.

+0

Semblable à ce que j'ai fait, mais je vis avec l'héritage du modèle. –

+0

Complètement compréhensible et valide, il m'a énervé à aucune fin si :) – Xealot

+0

Alors que dites-vous maintenant? Que je dois aller pour le backend d'authentification pour éditer le modèle d'utilisateur Django original? Si oui, copier le répertoire contrib.auth dans mon propre projet est suffisant, et compréhensible pour Django lors de l'ajout à mes paramètres? – Boemknaldaarstaatieal