My 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)
I use BaseProfile to map user_id to specific user_type. I wanted to use ProxyProfile as proxy which loads user_type depending profiles to ModelForm as shown below
Content of my forms.py:
class ProfileForm(ModelForm):
...
class Meta:
model = ProxyProfile
exclude = ('user','user_type')
...
ProfileForm is provided to django-profiles using following code in urls.py:
urlpatterns += patterns('',
url(r'^profiles/edit/', edit_profile,
{'form_class': ProfileForm},
name='profiles_edit_profile'),
(r'^profiles/',include('profiles.urls')),
)
I’ve also set in settings.py:
AUTH_PROFILE_MODULE = 'main.ProxyProfile'
During user registration all db data is filled correctly (it looks like everything is OK).
I register using form passed to django-registration:
urlpatterns += patterns('',
url(r'^register/$', register,
{'form_class': UserRegistrationForm},
name='registration.views.register'),
(r'', include('registration.urls')),
)
from 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
And registration phase works OK.
I’ve problem with profile edit/details pages.
My profiles filtered in ProxyProfile model and used as FormModel in ProfileForm
are not rendered (I can’t see profile specific fields are not rendered to HTML page)
Maybe there is some other way (more like Django way :)) to do this
(select and render profile model depending on user_type field which is related to User model).
Thanks in advance 🙂
Ok, finally I’ve had an idea how I can do this 🙂
In my models.py:
In custom manager – BaseManager I return profile object by overwriting get() method used by get_profile. I have to use UserManager named simply ‘manager’ to prevent recursive call of custom manager when assigning self.bt
OK, this is a half way to achive what I want, now I can view different profiles attached to users using django-profiles app.
Next, I want to use ModelForm to prepare edit form for user profiles. Users can have different profiles so I’ve applied the magic trick presented in this snippet: http://djangosnippets.org/snippets/2081/
And now in my forms.py I have:
next, simple model forms for each profile are assembled in ProfileForm:
In settings.py:
And it works like a charm but I wonder if it is the Django way to achieve support for multiple different profiles using django-profiles?
It worries me that I have to use get() few more times before I render profile details or edit form.
But after 4 days of struggling with Django to get this done finally I can sleep well tonight 🙂
Cheers