Different user profiles with django-profiles & django-registration -
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 map user_id specific user_type. wanted use proxyprofile proxy loads user_type depending profiles modelform shown below
content of forms.py:
class profileform(modelform): ... class meta: model = proxyprofile exclude = ('user','user_type') ...
profileform provided 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 set in settings.py:
auth_profile_module = 'main.proxyprofile'
during user registration db data filled correctly (it looks ok). register using form passed 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 profile edit/details pages. profiles filtered in proxyprofile model , used formmodel in profileform not rendered (i can't see profile specific fields not rendered html page) maybe there other way (more django way :)) (select , render profile model depending on user_type field related user model).
thanks in advance :)
ok, i've had idea how can :)
in 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 custom manager - basemanager return profile object overwriting get() method used get_profile. have use usermanager named 'manager' prevent recursive call of custom manager when assigning self.bt
ok, half way achive want, can view different profiles attached users using django-profiles app.
next, want use modelform prepare edit form user profiles. users can have different profiles i've applied magic trick presented in snippet: http://djangosnippets.org/snippets/2081/
and in forms.py have:
class freeform(forms.modelform): class meta: model = freeprofile class premiumform(forms.modelform): class meta: model = premiumprofile
next, simple model forms each profile assembled in 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): ...
in settings.py:
auth_profile_module = 'main.baseprofile'
and works charm wonder if django way achieve support multiple different profiles using django-profiles? worries me have use get() few more times before render profile details or edit form.
but after 4 days of struggling django done can sleep tonight :)
cheers
Comments
Post a Comment