0

I have this model as an extension of the built in User model:

class userprofile(models.Model):

    phone = models.CharField(max_length=20)
    address = models.CharField(max_length=500)
    user = models.OneToOneField(User, on_delete=models.CASCADE)

    @receiver(post_save, sender=User)
    def create_user_profile(sender, instance, created, **kwargs):
        if created:
            userprofile.objects.create(user=instance)

    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        instance.userprofile.save()

The django form class for creation of these models are:

class UserRegister(forms.Form):

    first_name = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'First Name'}))
    last_name = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Last Name'}))
    username = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Username'}))
    email = forms.EmailField( required=True, widget=forms.widgets.EmailInput(attrs={'placeholder': 'Email'}))
    password =forms.CharField(required=True, widget=forms.widgets.PasswordInput())
    confirm_password =forms.CharField(required=True, widget=forms.widgets.PasswordInput())

    class Meta:
        model=User
        fields=['first_name','last_name','username','email','password','confirm_password']




   def clean(self):
        cleaned_data = super(UserRegister, self).clean()
        password = cleaned_data.get("password")
        confirm_password = cleaned_data.get("confirm_password")
        if password != confirm_password:
            raise forms.ValidationError(
                "password and confirm_password does not match"
            )



class UserProfileCreate(forms.Form):
    mobile = forms.CharField(required=True, widget=forms.widgets.NumberInput(attrs={'placeholder': 'Mobile No.'}))
    address = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Delivery address'}))

    class Meta:
        model= userprofile
        fields=['mobile', 'address']

The HTML is like:

<form class="form-horizontal" method="POST" action="{% url 'createuser' %}">



                            {% csrf_token %}



                           {% for hidden in form.hidden_fields %}
                              {{ hidden }}
                            {% endfor %}

                            {% for field in form.visible_fields %}
                              <div class="form-group">
                                <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                                {{ field|add_class:'form-control' }}
                                {% for error in field.errors %}
                                  <span class="help-block">{{ error }}</span>
                                {% endfor %}
                              </div>
                            {% endfor %}

                            {% for field in formplus.visible_fields %}
                              <div class="form-group">
                                <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                                {{ field|add_class:'form-control' }}
                                {% for error in field.errors %}
                                  <span class="help-block">{{ error }}</span>
                                {% endfor %}
                              </div>
                            {% endfor %}

                            <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Register
                                </button>
                            </div>
                        </div>
                    </form>

And the view is as:

def create(request):
    if request.method == "GET":
        return render(request, 'userextension/usercreate.html', {'form' : UserRegister, 'formplus' : UserProfileCreate , 'message': 'Create your account'})

    else:
        user = UserRegister(request.POST)
        profile= UserProfileCreate(request.POST)
        if user.is_valid():
            if user.save():
                return render(request, 'userextension/usercreate.html', {'form' : UserRegister, 'message': 'Account created successfully'})




        return render(request, 'userextension/usercreate.html', {'form' : UserRegister, 'message': 'Could not create account'})

I did this thing after following some django tutorials. I do not see any improper code anywhere but I am unable to save the thus submitted form as a model. I didnt do userprofile.save() in the views.py since it is connected by OneToOneField to User and Ive mentioned for auto creation of userprofile whenever User is created.

Neither any error is raised nor the account is created. Could you guys give it a skim please?

Bill F
  • 723
  • 11
  • 23
  • Have you checked that `user.is_valid()` is actually returning `True`? I don't think it would, because you are missing `confirm_password` in the `fields`, and yet that field is required. – solarissmoke Apr 21 '18 at 03:14
  • I was thinking that fields would contain the fields that are present in the model itself but I was wrong. Thank you for this. But still, the problem is the same even after Ive added confirm_password in the fields. –  Apr 21 '18 at 03:25

1 Answers1

0

There are several problems here. The main one is that your user form is not valid. But you're not passing the invalid form back to the template, so you can't ever see why it is not valid. Instead of passing the class, you should pass the already-created instance.

return render(request, 'userextension/usercreate.html', {'form' : user, 'message': 'Could not create account'})

A second issue is that you never do anything with the profile form - you don't check it is valid, and you don't save it.

Also note you should always redirect after a successful post.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thank you for the response. I'm having quite a trouble figuring out how to redirect the invalid form back to the template. Could you please add some light in that regard. And also, Im not saving UserProfile instance because it is linked via a OneToOneField with the User and is automatically created when User is created for which I have mentioned in its model. –  Apr 21 '18 at 14:23
  • I don't understand, I showed you how to pass the invalid form back to the template. – Daniel Roseman Apr 21 '18 at 14:26
  • Oops , my bad. Sorry for the trouble. –  Apr 21 '18 at 14:39
  • It seems that I was making some couple of other dumb mistakes as well, but the core problem of my question above was addressed by redirecting the current instance. So, I'm marking this as accepted. Thanks mate –  Apr 21 '18 at 14:52