Verschiedene Benutzerprofile mit django-Profile & django-Registrierung
-
04-10-2019 - |
Frage
Meine 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)
Ich verwende BaseProfile auf bestimmte user_type abzubilden User_id. Ich wollte ProxyProfile als Proxy verwenden, die Lasten Profile Modelform user_type abhängig, wie unten gezeigt
Inhalt meiner forms.py:
class ProfileForm(ModelForm):
...
class Meta:
model = ProxyProfile
exclude = ('user','user_type')
...
ProfileForm ist vorgesehen, um django-Profile folgenden Code in urls.py mit:
urlpatterns += patterns('',
url(r'^profiles/edit/', edit_profile,
{'form_class': ProfileForm},
name='profiles_edit_profile'),
(r'^profiles/',include('profiles.urls')),
)
Ich habe auch in settings.py gesetzt:
AUTH_PROFILE_MODULE = 'main.ProxyProfile'
Während der Benutzerregistrierung alle db Daten korrekt gefüllt ist (es sieht aus wie alles in Ordnung ist). I-Register mit dem Formular übergeben django-Anmeldung:
urlpatterns += patterns('',
url(r'^register/$', register,
{'form_class': UserRegistrationForm},
name='registration.views.register'),
(r'', include('registration.urls')),
)
von 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
Und Registrierungsphase funktioniert OK.
Ich habe Problem mit Profil bearbeiten / Detailseite. Meine Profile in ProxyProfile Modell gefiltert und als FormModel in ProfileForm nicht erbracht werden (ich kann nicht profilspezifische Felder werden nicht in HTML-Seite gerendert sehen) Vielleicht gibt es eine andere Art und Weise (mehr wie Django Weg :)), dies zu tun (Wahlen und Profilmodell macht je nach user_type Feld, das auf Benutzermodell verwendet ist).
Vielen Dank im Voraus:)
Lösung
Ok, schließlich habe ich eine Idee hat, wie ich das tun kann:)
In meinem 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)
...
In benutzerdefinierten Manager - BaseManager I Rendite Objekt durch Überschreibung get () -Methode von get_profile verwendet. Ich muss einfach Usermanager ‚Manager‘ genannt verwenden rekursive Aufruf von benutzerdefinierten Manager zu verhindern, wenn self.bt
ZuweisenOK, das ist ein halber Weg achive, was ich will, kann ich jetzt verschiedene Profile ansehen django-Profile App an Benutzern verwendet wird.
Als nächstes möchte ich Modelform verwenden, bearbeiten Formular für Benutzerprofile herzustellen. Benutzer können unterschiedliche Profile haben, damit ich die magischen Trick in diesem Snippet dargestellt angewendet haben: http://djangosnippets.org/ Schnipsel / 2081 /
Und jetzt in meinem forms.py ich habe:
class FreeForm(forms.ModelForm):
class Meta:
model = FreeProfile
class PremiumForm(forms.ModelForm):
class Meta:
model = PremiumProfile
Als nächstes einfache Modellformen für jedes Profil sind in ProfileForm zusammengesetzt:
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):
...
In settings.py:
AUTH_PROFILE_MODULE = 'main.BaseProfile'
Und es wirkt wie ein Zauber, aber ich frage mich, ob es die Django Weg ist die Unterstützung für mehrere unterschiedliche Profile mit django-Profile zu erreichen? Es macht mir Sorgen, dass ich verwendet zu haben () einige Male, bevor ich dieses Profil oder bearbeiten Form machen.
Aber nach 4 Tagen mit Django kämpfen diese endlich kann ich heute Nacht gut schlafen zu erledigen:)
Prost