Django-Profils D'Utilisateurs Multiples
initialement, j'ai commencé mon profile D'utilisateur comme ceci:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OneToOneField(User)
verified = models.BooleanField()
mobile = models.CharField(max_length=32)
def __unicode__(self):
return self.user.email
Qui fonctionne très bien avec .
cependant, j'ai deux types différents d'utilisateurs dans mon site web, les individus et L'entreprise, chacun ayant leurs propres attributs uniques. Par exemple, je voudrais que mes utilisateurs individuels n'aient qu'un seul utilisateur, donc user = models.OneToOneField(User)
et pour l'Entreprise j'ai envie d'avoir plusieurs utilisateurs sur le même profil, donc j'aurais user = models.ForeignKey(User)
à la place.
alors j'ai pensé à séparer le modèle en deux modèles différents,IndivProfile
et CorpProfile
, les deux héritant de UserProfile
tout en déplaçant les attributs spécifiques au modèle dans les sous-modèles pertinents. Semble être une bonne idée pour moi et serait probablement travailler, mais je ne serais pas en mesure de spécifier AUTH_PROFILE_MODULE
de cette façon puisque j'ai deux profils d'utilisateurs qui seraient différents pour des utilisateurs différents.
j'ai aussi pensé à le faire dans l'autre sens, avoir UserProfile
hériter de classes multiples (models), quelque chose comme ceci:
class UserProfile(IndivProfile, CorpProfile):
# some field
def __unicode__(self):
return self.user.email
de Cette façon, je mettrais AUTH_PROFILE_MODULE = 'accounts.UserProfile'
et résoudre son problème. Mais ça n'a pas l'air de marcher, puisque l'héritage en python fonctionne de gauche à droite et toutes les variables en IndivProfile
sera dominante.
bien Sûr, je peux toujours avoir un modèle unique, avec IndivProfile
et CorpProfile
les variables sont toutes mélangées ensemble et j'utiliserais les variables requises si nécessaire. Mais c'est cela ne me semble pas propre, je préférerais les séparer et utiliser le modèle approprié à l'endroit approprié.
toute suggestion de clean comment faire cela?
3 réponses
Vous pouvez le faire de la manière suivante. Avoir un profil qui contient des champs qui sont nécessaires dans les deux profils. Et vous l'avez déjà fait en créant class UserProfile
.
class UserProfile(models.Model):
user = models.ForeignKey(User)
#some common fields here, which are shared among both corporate and individual profiles
class CorporateUser(models.Model):
profile = models.ForeignKey(UserProfile)
#corporate fields here
class Meta:
db_table = 'corporate_user'
class IndividualUser(models.Model):
profile = models.ForeignKey(UserProfile)
#Individual user fields here
class Meta:
db_table = 'individual_user'
il n'y a pas de science de fusée en jeu ici. Il suffit d'avoir un mot-clé qui fera la distinction entre le profil d'entreprise ou le profil individuel. Par exemple: Considérez que l'utilisateur s'inscrit. Ensuite, avoir un champ sur le formulaire qui différenciera si l'utilisateur s'inscrit pour l'entreprise ou non. Et utilisez ce mot-clé (paramètre request) pour enregistrer l'utilisateur dans le modèle respectif.
puis plus tard, quand jamais vous voulez vérifier que le profil de l'utilisateur est corporatif ou individuel, vous pouvez le vérifier en écrivant une petite fonction.
def is_corporate_profile(profile):
try:
profile.corporate_user
return True
except:
return False
#If there is no corporate profile is associated with main profile then it will raise exception and it means its individual profile
#you can use this function as a template function also to use in template
{%if profile|is_corporate_profile %}
espérons que cela vous mènera où. Merci
j'ai fait de cette manière.
PROFILE_TYPES = (
(u'INDV', 'Individual'),
(u'CORP', 'Corporate'),
)
# used just to define the relation between User and Profile
class UserProfile(models.Model):
user = models.ForeignKey(User)
profile = models.ForeignKey('Profile')
type = models.CharField(choices=PROFILE_TYPES, max_length=16)
# common fields reside here
class Profile(models.Model):
verified = models.BooleanField(default=False)
j'ai fini par utiliser un tableau intermédiaire pour refléter la relation entre deux modèles abstraits,User
qui est déjà défini dans Django, et mon Profile
modèle. Dans le cas d'attributs qui ne sont pas communs, je vais créer un nouveau modèle et de le rapporter à Profile
.
pourrait être utile pour essayer d'utiliser un champ de travers. L'idée sous-jacente est d'utiliser le modèle UserProfile comme modèle à travers pour les modèles CorpProfile ou IndivProfile. De cette façon, il est créé dès qu'un Corp ou Indiv Profil est lié à un utilisateur:
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.ForeignKey(User)
profile = models.ForeignKey(Profile, related_name='special_profile')
class Profile(models.Model):
common_property=something
class CorpProfile(Profile):
user=models.ForeignKey(User, through=UserProfile)
corp_property1=someproperty1
corp_property2=someproperty2
class IndivProfile(Profile):
user=models.ForeignKey(User, through=UserProfile, unique=true)
indiv_property1=something
indiv_property2=something
je pense que la façon dont il devrait être possible de définir AUTH_PROFILE_MODULE = 'accounts.UserProfile'
, et à chaque fois que vous créez un fichier CorpProfile ou un fichier indiv qui est lié à un utilisateur réel, un modèle UserProfile unique est créé. Vous pouvez alors y accéder avec les requêtes db ou ce que vous voulez.
je n'ai pas testé, donc pas garanties. Il peut être un peu hacky, mais d'un autre côté, je trouve l'idée assez intéressante. :)