Shufi123
Shufi123

Reputation: 233

User ModelForm not getting saved in database (Django)

I have a ModelForm that creates an instance of a custom user (AbstractUser model). Whenever I try to submit the form, nothing happens except a reload of the page (because of the action), and nothing is getting saved in the database. The code is as following:

def sign_up(request):
    if request.method == 'POST':
        print("test")
        form = UserForm(request.POST)
        if form.is_valid():
            form.save()
            data = form.cleaned_data
            user = authenticate(
                username=data['username'],
                password=data['password']
            )
            user_login(request, user)
    else:
        form = UserForm()
    return render(request, 'schedules/signup/signup.html', {'form':form})
class ClientUser(AbstractUser):
    classes = models.ManyToManyField(ScheduleClass)
    personal_changes = models.TextField(name="personal_changes", default="none")
    schedule = models.ManyToManyField(Schedule)
    def get_classes(self):
        return self.classes
class UserForm(forms.ModelForm):

    class Meta:
        model = ClientUser
        fields = ['username', 'password', 'classes', 'schedule']
        <form method="post" action="http://127.0.0.1:8000/">
            {% csrf_token %}
            {{ form }}
            <input type="submit">
        </form>

For some reason, it's also not even printing the line I wrote on line 3 of the sign_up func, even when I post. Is there something I am doing wrong?

Upvotes: 1

Views: 254

Answers (1)

markwalker_
markwalker_

Reputation: 12869

Ok, so you said your print isn't showing, so first off make your form action relative to the site, using django's {% url template tag is often a good idea here, or just leaving it blank to post to the current URL;

        <form method="post" action="">
            {% csrf_token %}
            {{ form }}
            <input type="submit">
        </form>

Now if you hit the view with your POST request and the form isn't valid, what you're doing at the moment won't include any errors when the page is rendered again so it'll look like nothing happened when in actual fact you did try to validate the form, you just didn't return the errors to the user.

Once you call form.is_valid(), errors are added to that form instance if it isn't valid. So the state of the form instance is really important and you need to pass it back to the user rather than creating a new one which is how you're getting rid of the errors.

You'd do something like this;

def sign_up(request):
    # Create the form for a GET request
    form = UserForm()

    if request.method == 'POST':
        # Recreate the form instance with the POST data
        form = UserForm(request.POST)
        # Run form validation
        if form.is_valid():
            form.save()
            data = form.cleaned_data
            user = authenticate(
                username=data['username'],
                password=data['password']
            )
            user_login(request, user)

    # if you end up here on a POST request, the form isn't valid but still contains the errors
    return render(request, 'schedules/signup/signup.html', {'form':form})

Upvotes: 1

Related Questions