0

I need your help. I extending class User and add same field, than extending UserCreationForm, but form is not valid. Code crash in if form.is_valid(). Please help, why my form is not correctly?

models.py

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

My register form

forms.py

class MyRegisterForm(UserCreationForm):
print "OK!"
nick_name = forms.CharField(max_length=30, required=True, widget=forms.TextInput)
print "Ook"
class Meta:
    model = UserProfile
def save(self, commit=True):
    if not commit:
        raise NotImplementedError("Can't create User and UserProfile without database save")
    print "Saving..."
    user = super(MyRegisterForm, self).save(commit=False)
    user.nick_name = self.cleaned_data["nick_name"]
    user_profile = UserProfile(user=user, nick_name=self.cleaned_data['nick_name'])
    user_profile.save()
    print "Saving complete"
    return user, user_profile

Register function

views.py

def reg(request):
    if request.method =='POST':
        form = MyRegisterForm(request.POST)
        if form.is_valid():
            username = form.cleaned_data['username']
            print username
            password1 = form.cleaned_data['password1']
            print password1
            password2 = form.cleaned_data['password2']
            print password2
            nick_name = form.cleaned_data['nick_name']
            print nick_name
            form.clean_username()
            if password1 == password2:
                new_user = form.save()
                return render_to_response('registration/registration_complete.html')
            else:
                print "Password error"
                return render_to_response('registration/registration_fail.html')
        else:
            print "FORM error" #ТУТ ВАЛИТСЯ :(
            return render_to_response('registration/registration_fail.html')
    else:
        form = UserCreationForm() # An unbound form
    return render_to_response('registration/registration_new_user.html', {
        'form': form,
        },context_instance=RequestContext(request))

In setting

settings.py

AUTH_PROFILE_MODULE = 'registration.UserProfile'

Registration template

registration_new_user.html

    {% extends "base.html" %}
{% block content %}
  <h1>Registration</h1>
  <form action="registration" method="post">
    {% if form.error_dict %}
      <p class="error">Please fix the error.</p>
    {% endif %}
    {% if form.username.errors %}
      {{ form.username.html_error_list }}
    {% endif %}
    <label for="id_username">Login:</label><br> {{ form.username }}<br>
    {% if form.password1.errors %}
      {{ form.password1.html_error_list }}
    {% endif %}
    <label for="id_password1">pass:</label><br> {{ form.password1 }}<br>
    {% if form.password2.errors %}
      {{ form.password2.html_error_list }}
    {% endif %}
    <label for="id_password2">pass(again):</label><br> {{ form.password2 }}<br>
    {% if form.nick_name.errors %}
      {{ form.nick_name.html_error_list }}
    {% endif %}
    <label for="id_nick_name">nick:</label><br> {{ form.nick_name }}<br>
      <br>
    <input type="submit" value="Reg" />
  </form>
{% endblock %}
15
  • Is the indentation just a miss or...? Commented May 17, 2013 at 11:48
  • @lov3catch: In python indentation is part of the syntax. Likewise, please indent your code in the question so that everyone knows what is your code. Commented May 17, 2013 at 12:45
  • What error are the form returning? Commented May 17, 2013 at 12:53
  • @PauloBu: any error in console & any error in browser. Just print: FORM error Commented May 17, 2013 at 13:07
  • Yes but, is it an exception, are there normal forms errors for fields missing? If so, can you post what happens when you submit? That will lead us a little :) Commented May 17, 2013 at 13:12

1 Answer 1

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!

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

3 Comments

thx you! You are awesome. form = MyRegistrationForm() # An unbound form this code fix my template, and now I see fields for input nick-name. But registration is not work. Traceback: 'UserProfile' object has no attribute 'set_password'
Code was stopped in this line: user_profile = super(MyRegisterForm, self).save(commit=False)
I confused and go to created mini-project with only registration for understanding how it works. Thx you verymuch.

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.