Différents profils d'utilisateurs avec django-profils et django-inscription
-
04-10-2019 - |
Question
Mon models.py:
USER_TYPES = (
('D', 'Demo' ),
('F', 'Free' ),
('P', 'Premium'),
)
class BaseProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
user_type = models.CharField(max_length=1, blank=True, choices=USER_TYPES)
class DemoProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
demo = models.CharField(max_length=10, blank=True)
...
class FreeProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
free = models.CharField(max_length=10, blank=True)
...
class PremiumProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
premium = models.CharField(max_length=10, blank=True)
...
class ProxyProfile(BaseProfile):
class Meta:
proxy = True
def get_profile(self):
if self.user_type == 'D':
return DemoProfile._default_manager.get(user__id__exact=self.user_id)
elif self.user_type == 'F':
return FreeProfile._default_manager.get(user__id__exact=self.user_id)
else:
return PremiumProfile._default_manager.get(user__id__exact=self.user_id)
J'utilise BaseProfile à la carte user_id à user_type spécifique. Je voulais utiliser ProxyProfile comme proxy qui, comme indiqué ci-dessous des charges user_type en fonction des profils à ModelForm
Contenu de mon forms.py:
class ProfileForm(ModelForm):
...
class Meta:
model = ProxyProfile
exclude = ('user','user_type')
...
ProfileForm est prévu pour django-profils à l'aide du code suivant dans urls.py:
urlpatterns += patterns('',
url(r'^profiles/edit/', edit_profile,
{'form_class': ProfileForm},
name='profiles_edit_profile'),
(r'^profiles/',include('profiles.urls')),
)
Je l'ai également mis en settings.py:
AUTH_PROFILE_MODULE = 'main.ProxyProfile'
Lors de l'enregistrement de l'utilisateur toutes les données db est rempli correctement (il semble que tout est OK). Je me inscrire en utilisant le formulaire passé à django-inscription:
urlpatterns += patterns('',
url(r'^register/$', register,
{'form_class': UserRegistrationForm},
name='registration.views.register'),
(r'', include('registration.urls')),
)
de forms.py:
class UserRegistrationForm(RegistrationFormUniqueEmail, RegistrationFormTermsOfService):
utype = forms.ChoiceField(choices=USER_CHOICES)
def save(self, profile_callback=None):
new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'],
password.self.cleaned_data['password1'],
email=self.cleaned_data['email'],
)
new_base_profile = BaseProfile(user=new_user, user_type=self.cleaned_data['utype'])
if self.cleaned_data['utype'] == "D":
new_profile = DemoProfile(user=new_user)
if self.cleaned_data['utype'] == "F":
new_profile = FreeProfile(user=new_user)
if self.cleaned_data['utype'] == "P":
new_profile = PremiumProfile(user=new_user)
new_profile.save()
new_base_profile.save()
return new_user
phase d'enregistrement fonctionne OK.
J'ai un problème pages profil d'édition / détails. Mes profils filtrés dans le modèle ProxyProfile et utilisé comme FormModel dans ProfileForm ne sont pas rendus (je ne peux pas voir les champs spécifiques de profil ne sont pas rendus à la page HTML) Peut-être il y a une autre façon (plus comme Django façon :)) pour faire (Sélectionner et rendre le modèle de profil en fonction de champ user_type qui est liée au modèle d'utilisateur).
Merci à l'avance:)
La solution
Ok, enfin j'ai eu une idée comment je peux le faire:)
Dans mon models.py:
class BaseManager(models.Manager):
def get(self, **kwargs):
self.u = kwargs['user__id__exact']
self.bt = BaseProfile.manager.get(user__id__exact=self.u)
if self.bt.user_type == 'F':
return FreeProfile.objects.get(pk=self.u)
elif self.bt.user_type == 'I':
return PremiumProfile.objects.get(pk=self.u)
else:
return None
class BaseProfile(models.Model):
objects = BaseManager()
manager = UserManager()
user = models.OneToOneField(User, primary_key=True)
user_type = models.CharField(max_length=1, blank=True, choices=USER_TYPES)
class FreeProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
free = models.CharField(max_length=10, blank=True)
...
class PremiumProfile(models.Model):
user = models.OneToOneField(User, primary_key=True)
premium = models.CharField(max_length=10, blank=True)
...
Dans le Gestionnaire personnalisé - BaseManager I retour objet profil méthode get écrasement () utilisée par get_profile. Je dois utiliser UserManager nommé simplement « gestionnaire » pour empêcher appel récursif de gestionnaire personnalisé lors de l'attribution self.bt
OK, c'est une façon de moitié à achive ce que je veux, maintenant, je peux voir les différents profils attachés à des utilisateurs en utilisant l'application de profils django.
Ensuite, je veux utiliser ModelForm pour préparer formulaire de modification pour les profils utilisateur. Les utilisateurs peuvent avoir des profils différents, donc j'ai appliqué le truc magique présenté dans cet extrait: http://djangosnippets.org/ extraits / 2081 /
Et maintenant, dans mon forms.py je:
class FreeForm(forms.ModelForm):
class Meta:
model = FreeProfile
class PremiumForm(forms.ModelForm):
class Meta:
model = PremiumProfile
suivante, des formes simples de modèle pour chaque profil sont assemblés en ProfileForm:
class ProfileForm(ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs['instance'].user
profile_kwargs = kwargs.copy()
profile_kwargs['instance'] = self.user
self.bt = BaseProfile.manager.get(user__id__exact=self.user.id)
if self.bt.user_type == 'F':
self.profile_fields = FreeForm(*args, **profile_kwargs)
elif self.bt.user_type == 'P':
self.profile_fields = PremiumForm(*args, **profile_kwargs)
super(ProfileForm, self).__init__(*args, **kwargs)
self.fields.update(self.profile_fields.fields)
self.initial.update(self.profile_fields.initial)
class Meta:
model = BaseProfile
def save(self):
...
En settings.py:
AUTH_PROFILE_MODULE = 'main.BaseProfile'
Et cela fonctionne comme un charme, mais je me demande si c'est la façon de Django pour obtenir le soutien de plusieurs profils différents en utilisant des profils de django-? Il me inquiète que je dois utiliser get () quelques fois avant que je rends les détails de profil ou le formulaire.
Mais au bout de 4 jours de lutte avec Django pour obtenir ce que je peux faire enfin bien dormir ce soir:)
Vive