[Answer]-Extending User and UserCreationForm

1👍

Well, you have several issues in your code. For instance, you override UserCreationForm with MyRegistrationForm and indeed you instantiate the latter when the request is a POST, but when is not, you pass the template a normal UserCreationForm.

You do have a user in your UserCreationForm because this is a ModelForm whose model is UserProfile and there you have defined a user field. So it makes perfect sense that the forms complaint about this when you create it with the POST.

I don’t see a very clear solution here because your code is somewhat tricky but first of all, use the same form with both GET and POST request type so this line in your views

form = UserCreationForm() # An unbound form

Would change for this one:

form = MyRegistrationForm() # An unbound form

In the template it won’t appear the field user because you don’t include them but it is in the form. As you are creating a new user, that field should be set to non-required because no user will be associated with the UserProfile because you are creating the user. You can set it to non-required adding the parameter blank=True to the model:

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique=True, related_name='profile', blank=True)
    nick_name = models.CharField(max_length=15)

UPDATE:

This is the code for your base class UserCreationForm save method:

def save(self, commit=True):
    user = super(UserCreationForm, self).save(commit=False)
    user.set_password(self.cleaned_data["password1"])
    if commit:
        user.save()
    return user

As you can see, this code assumes that the user has a set_password attribute, in order to fix this, you have to add a def set_password(self, raw_password) method to your UserProfile class. This error happens because the form base class is designed to be used with normal Django User class, any other error you may encounter like this you will probably solve it by adding the fields required to your UserProfile. This one solves like this:

class UserProfile:
    ...
    def set_password(self, raw_password):
        # whatever logic you need to set the password for your user or maybe
        self.user.set_password(raw_password)
    ...

I hope this bring some light to the problem. Good luck!

Leave a comment