0

I created a model for my website's users:

class ImrayWebsiteUser(models.Model):
    user = models.OneToOneField(User) 
    score = models.IntegerField(default=0)   
    birthDate = models.DateField(null=True,blank=True)
    clubs = models.ManyToManyField(Club)

In Views, I created a page for new users to register. When they click register (after filling the form) I created another View that checks a form and saves the users data if it's valid.

Here's the View:

def register_user(request):
    if request.method == 'POST':
        form = MyRegistrationForm(request.POST)
        if form.is_valid():
            form.save() #save user registeration data
            return HttpResponseRedirect('/accounts/register_success') 

    # in the first time it generate empty form:
    args = {}
    args.update(csrf(request))

    args['form'] = MyRegistrationForm()

    return render_to_response('accounts/register.html', args)

And the form:

class MyRegistrationForm(UserCreationForm):
    email = forms.EmailField(required=True)
    first_name = forms.CharField(required=False,max_length=30)
    last_name = forms.CharField(required=False,max_length=30)

    class Meta:
        model = ImrayWebsiteUser
        fields = ('username', 'email', 'password1', 'password2',
                  'first_name', 'last_name')

    def save(self, commit=True):
        user = super(MyRegistrationForm, self).save(commit=False)
        user.email = self.cleaned_data['email']
        user.firstname = self.cleaned_data['first_name']
        user.lastname = self.cleaned_data['last_name']
        # user.set_password(self.cleaned_data['password1'])

        if commit:
            user.save()

        return user

The problem is, when I fill in the form information, and click register (thus executing the View and sending the data to the form) I get an AttributeError saying that ImrayWebsiteUser has no attribute called set_password. This shouldn't happen though, since my user ImrayWebsiteUser clearly implements the built in User type.

This is the error code:

AttributeError at /accounts/register/
'ImrayWebsiteUser' object has no attribute 'set_password'
Request Method: POST
Request URL:    http://127.0.0.1:8000/accounts/register/
Django Version: 1.5
Exception Type: AttributeError
Exception Value:    
'ImrayWebsiteUser' object has no attribute 'set_password'
Exception Location: C:\Python27\lib\site-packages\django\contrib\auth\forms.py in save, line 107
Python Executable:  C:\Python27\python.exe
Python Version: 2.7.6
Python Path:    
['C:\\Users\\Imray\\ImraySite\\bitbucket',
 'C:\\Python27\\lib\\site-packages\\setuptools-2.1-py2.7.egg',
 'C:\\Windows\\SYSTEM32\\python27.zip',
 'C:\\Python27\\DLLs',
 'C:\\Python27\\lib',
 'C:\\Python27\\lib\\plat-win',
 'C:\\Python27\\lib\\lib-tk',
 'C:\\Python27',
 'C:\\Python27\\lib\\site-packages']
Server time:    Thu, 13 Mar 2014 11:56:27 +0200

1 Answer 1

1

Your OnetoOneField is not implementation of User model.

https://docs.djangoproject.com/en/1.6/ref/models/fields/#ref-onetoone

You can access OneToOneField as object.user attribute in your case.

Since you are using inbuilt UserCreationForm which implements set_password, you can create a method in your model called set_password and call self.user.set_password

But I recommend you look into custom user implementation:

https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#auth-custom-user

EDIT: This is just a concept according to what I got from your question:

class UserProfile(models.Model):
  user = models.OneToOneField(User)
  .....your other attributes

also for RegistrationForm you could do something like:

class MyRegistrationForm(UserCreationForm):
  ....your registration form attributes from UserProfile Model
  class Meta:
    fields = ('username', 'email', 'firstname', 'lastname')  # fields of User Model not your UserProfile Model

  def save(self, commit=True):
     user = super(MyRegistrationForm, self).save(commit=commit)
     userprofile = UserProfile(user=user)
     userprofile.attribute = form.cleaned_data[attribute_name]...
     return user|userprofile #as required

Also csrf is already available in template as {% csrf_token %}

Sign up to request clarification or add additional context in comments.

4 Comments

Really the only difference between my user and the built-in user type is that my user has some relationships with other models in my project. Should I be implementing my own user another way?
Also can you tell me, or point me to where I can find out what self actually is? (Not in a Platonic sense, but in the sense of what object is it - is it a session? is it a user? What can I typically do with it?)
self is the the object argument from which class is initialized/called. It is something like this in c++ or java. In python world Explicit is better than implicit.. Basically what you can do is create foreignkey to inbuilt user model and just add extra fields[Not provided by user model itself].
I tried you instructions, but it was not successful. I'm still getting errors (DoesNotExist)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.