1

I am stuck at user registration, I actually intends to have different profile types. While registration I am unable to set UserProfile while creating a user. I am using UserCreationForm. code in my files are as following.

from django.contrib.auth.forms import UserCreationForm
from registration.forms import RegistrationForm
from django import forms
from django.contrib.auth.models import User
from accounts.models import UserProfile
from django.utils.translation import ugettext_lazy as _
from person.models import Person
from pprint import pprint


class UserRegistrationForm(UserCreationForm):
    #email = forms.EmailField(label = "Email")
    fullname = forms.CharField(label = "Full name")

    class Meta:
        model = User
        fields = ("email","fullname","password1","password2" )

    def __init__(self, *args, **kwargs):
        super(UserRegistrationForm, self).__init__(*args, **kwargs)
        del self.fields['username']

    def clean_email(self):
        """
        Validate that the supplied email address is unique for the
        site.

        """
        if User.objects.filter(email__iexact=self.cleaned_data['email']):
            raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
        return self.cleaned_data['email']

    def save(self, commit=True):
        user = super(UserRegistrationForm, self).save(commit=False)
        #user_profile=user.set_profile(profile_type="Person")

        UserProfile.profile.person.full_name = self.cleaned_data["fullname"]
        user.email = self.cleaned_data["email"]
        if commit:
            user.save()
        return user

class CompanyRegistrationForm(UserCreationForm):
    email=forms.EmailField(label="Email")

class UserProfileForm(forms.ModelForm):
    class Meta:
        model=UserProfile
        exclude=('user',)

accounts/models.py

    from django.db import models
from django.contrib.auth.models import User


class UserProfile(models.Model):
    user=models.OneToOneField(User) 
    meta_keywords=models.CharField("Meta Keywords",max_length=255,
            help_text="Comma delimited set of keywords of meta tag")
    meta_description=models.CharField("Meta Description",max_length=255,
            help_text='Content for description meta tag')

    def __unicode__(self):
        return "User Profile for: "+self.username

    class Meta:
        ordering=['-id']

views.py

    from django.contrib.auth.forms import UserCreationForm
from django.template import RequestContext
from django.shortcuts import render_to_response,get_object_or_404
from django.core import urlresolvers
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from accounts.forms import UserRegistrationForm, UserProfileForm
#from accounts.forms import UserProfile

def register(request,template_name="account/register.html"):
    if request.method=='POST':
        postdata=request.POST.copy()
        form=UserRegistrationForm(postdata)
        user_profile=UserProfileForm(postdata)
        if form.is_valid():
            form.save()
            un=postdata.get('username','')
            pw=postdata.get('password','')
            from django.contrib.auth import login,authenticate
            new_user=authenticate(username=un,password=pw)
            if new_user and new_user.is_active:
                login(request,new_user)
                url=urlresolvers.reverse('dashboard')
                return HttpResponseRedirect(url)     
    else:
        form=UserRegistrationForm()
    page_title="User Registration"
    return render_to_response(template_name,locals(),context_instance=RequestContext(request))


@login_required
def dashboard(request):
    pass

@login_required
def settings(request):
    pass

As I am using multiple profiles so following is code of one of those profiles' models.py:

    from django.db import models
from django.contrib.auth.models import User
from accounts.models import UserProfile

class Person(UserProfile):
    skills=models.CharField(max_length=100)
    fullname=models.CharField(max_length=50)
    short_description=models.CharField(max_length=255)
    is_online=models.BooleanField(default=False)
    tags=models.CharField(max_length=50)
    profile_pic=models.ImageField(upload_to="person_profile_images/")
    profile_url=models.URLField()
    date_of_birth=models.DateField()
    is_student=models.BooleanField(default=False)
    current_designation=models.CharField(max_length=50)
    is_active_jobseeker=models.BooleanField(default=True)
    current_education=models.BooleanField(default=True)


    class Meta:
        db_table='person'

My profile auth in settings.py

AUTH_PROFILE_MODULE='accounts.UserProfile'

Here is a file that also I used after looking at some other place, profile.py: from accounts.models import UserProfile from accounts.forms import UserProfileForm from person.models import Person from company.models import Company

def retrieve(request,profile_type):
    try:
        profile=request.user.get_profile()
    except UserProfile.DoesNotExist:
        if profile_type=='Person':
            profile=Person.objects.create(user=request.user)
        else:
            profile=Company.objects.create(user=request.user)
        profile.save()
    return profile

def set(request,profile_type):
    profile=retrieve(request,profile_type)
    profile_form=UserProfileForm(request.POST,instance=profile)
    profile_form.save()

I am new and confuse, have seen documentation also. Also saw other solutions at stackoverflow.com but didn't find any solution of my problem. So please tell if you find anything helpful for me. It doesn't seems to be a big problem but as I am new to it so it is a problem for me.

Hafiz
  • 4,187
  • 12
  • 58
  • 111

1 Answers1

2

Multiple profile types won't work with the OneToOne relation that is required by Django profile mechanism. I suggest you keep a single profile class containing data common to all profile types and you store type-specific data in a separate set of classes that you link to your profile class using a generic relation.

EDIT:

Thanks for the clarification. Looking at your code again today it seems that you might indeed be able to accomplish what your trying to do with model inheritance. I think the problem is in the save() method of UserRegistrationForm. Try something like this:

def save(self, commit=True):
    user = super(UserRegistrationForm, self).save(commit=False)
    user.email = self.cleaned_data["email"]
    if commit:
        user.save()
        person = Person(user=user)
        person.full_name = self.cleaned_data["fullname"]
        person.save()
    return user
Hafiz
  • 4,187
  • 12
  • 58
  • 111
Alex Marandon
  • 4,034
  • 2
  • 17
  • 21
  • What if I user Foreignkey with unique=True ? How will I connect it then? Because model wise, I already have done R&D so currently I am facing problem at connecting with profile, while registration of user as I haven't done it before. So I don't know how to connect that, whether parent class is USerProfile and 2 different Person and Company inherit from that. – Hafiz Apr 29 '12 at 19:49
  • So doing `Person(user=user)` will connect it to Person and also update the data in `UserProfile` and `Person` table? So django will understand all that connection by this statement? sorry for silly question but I am new in it so just want to understand, really thankful for your time for looking at it again – Hafiz Apr 30 '12 at 20:48
  • I think it should work. Haven't tested though. Have you tried it? Any issue in particular? – Alex Marandon May 02 '12 at 08:48
  • I have tested it right now, not working exactly as you told, but after doing some changes, it seems to work, will post exact code once it is completely working – Hafiz May 02 '12 at 11:50
  • I have edited the code, actually person object will initialize after user.save() has been called, so that it can have user_id field – Hafiz May 02 '12 at 12:39
  • 1
    Please review and accept my last edit so that it can be visible for others, so it may be helpful for others having similar problem – Hafiz May 02 '12 at 12:40
  • All right, that makes sense. So you edited my answer? I'm not sure if I'm allowed to review and accept your edit. I can't see where to do it... – Alex Marandon May 02 '12 at 13:40
  • OK got it now, I've approved your edit. Still learning how to use SO :) – Alex Marandon May 02 '12 at 13:42