3 votes

Ajouter une référence de modèle à un modèle existant

J'ai créé un module qui sert mon propre système d'authentification et d'utilisateurs. C'est un module universel que j'utilise dans différentes applications. Dans ce module, un User est décrit comme suit :

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)

Dans chaque application où j'utilise ce module, j'aimerais créer un modèle supplémentaire qui décrit les champs additionnels spécifiques à cette application, comme ceci :

 class UserProfile(db.Model):
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

Et j'ai besoin de joindre UserProfile modèle à User à l'intérieur de ma nouvelle application. Comment puis-je faire cela sans avoir à modifier le code à l'intérieur du module qui est commun à toutes les applications ?

2voto

Chris Farmiloe Points 7769

Si j'avais un module utilisateur que j'importais dans plusieurs projets, je traiterais ce module partagé comme un base pour construire mes applications.

Il se peut donc que vous ayez un baseuser.py module contenant :

class UserModel(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)

Ensuite, dans chaque projet GAE, vous auriez :

from baseuser import UserModel

class User(UserModel):
    first_name = db.StringProperty()
    last_name = db.StringProperty()
    company = db.StringProperty()

Vous seriez alors libre d'étendre vos modèles d'utilisateurs par application et de conserver toute la logique partagée en un seul endroit.

1voto

Drew Sears Points 10951

Au sein d'une même application, il s'agit donc vraisemblablement d'une relation univoque. L'endroit où vous stockez la référence est donc arbitraire. Vous pouvez simplement modifier votre modèle UserProfile pour référencer l'utilisateur :

class UserProfile(db.Model):
        user = db.ReferenceProperty(User)
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

Ensuite, dans le contrôleur :

user = User.filter('email =', email).get()
profile = UserProfile.filter('user =', user).get()

Si vous souhaitez que la référence soit conservée dans l'objet Utilisateur, mais qu'elle ne perturbe pas les applications qui ne prennent pas en charge un profil, vous pouvez également procéder de la manière suivante :

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)
    profile = db.ReferenceProperty()

Ici, vous spécifiez une référence de profil faible pour l'utilisateur. Elle n'est pas obligatoire, et si vous la remplissez, il n'est pas nécessaire que ce soit un modèle particulier. Cela vous permet de stocker optionnellement une référence de profil sans rompre la compatibilité.

Enfin, vous pouvez ignorer complètement le profil et créer simplement votre objet utilisateur. un Expando .

0voto

mgiuca Points 10265

Toutes les applications partagent-elles une base de données ? Dans ce cas, vous ne pouvez pas stocker le UserProfile en tant que champ du modèle User, car l'utilisateur n'a pas toujours un profil associé. Je ferais de l'utilisateur un champ de UserProfile et le ferais pointer dans cette direction (UserProfile contient un utilisateur), et je ferais de l'élément user de UserProfile indexé afin de pouvoir consulter rapidement le UserProfile d'un utilisateur donné.

Si vous souhaitez simplement réutiliser le code sans partager une base de données commune, vous pouvez rendre ces champs supplémentaires conditionnels en fonction de l'application. Par exemple :

class User(db.Model):
    email = db.EmailProperty()
    password = db.StringProperty()
    role = db.StringProperty(default=roles.USER)
    if APP_HAS_USER_PROFILES:
        first_name = db.StringProperty()
        last_name = db.StringProperty()
        company = db.StringProperty()

Ces trois derniers champs n'apparaîtront alors que dans certaines applications. Je crois qu'il est également possible de faire en sorte que UserProfile hérite de User, mais je ne suis pas sûr de ce qui se passe alors (en termes de base de données).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X