ModelForm isnt working

I found the error. I used the form in the profile page so the form and the page are having diffrent views and the view from the form was never used just the profile view. Now it works. Thanks!

but now after Submitting there is an diffrent error

django.db.utils.IntegrityError: NOT NULL constraint failed: StartSite_account.user_id

heres my models.py again

from django.db import models
from django.contrib.auth.models import User

class Account(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    prename = models.CharField(max_length=20, null=True)
    surname = models.CharField(max_length=40, null=True)
    company = models.CharField(max_length=40, null=True)
    profile_pic = models.CharField(max_length=40, null=True)
    country = models.CharField(max_length=40, null=True)
    packet_premium = models.BooleanField(null=True)
    packet_business = models.BooleanField(null=True)


    def __str__(self):
        return self.user.username



For clarity and precision - a form doesn’t use a view. Templates don’t use views.
Views use forms and templates. Yes, it’s just terminology, but precision here is valuable with understanding the relationships between the elements of a Django project.

Regarding the error - you don’t have user as a field in your form and you’re not assigning a value to user in your view. Since you don’t have null=True in that field in your model, then an exception is going to be thrown.

so I’ve addet null=True as a parameter in the field of my user but the error still appears. And in the register view I’ve set a value to the user field so it shouldn’t be empty.

So then you want to verify that your view is doing what you’re expecting it to do. (Or needing it to do.)

I tried to set the User in the view for the form aswell…

views.py

def AccountInfoPrename(request):
        if request.method == 'POST':
            form = AccountInfoPrenameForm(request.POST)
            if form.is_valid():
                Account.user = request.user.id
                Account.save()
                form.save()


            return redirect('home:profile')
        else:
            form = AccountInfoPrenameForm()
        return render(request,
                  'home/profile.html',
                  {'form': form}

                  )

And now another error appears:

TypeError: save() missing 1 required positional argument: 'self'

So did I make it worse or better?

Review the docs on the ModelForm.save() method, specifically, the text before the second example, and the second example, except for any references to ManyToMany fields - you can ignore those. (Do note that the example does not call form.is_valid - this does not mean you should remove that test, just that this example ignores the validation aspects of form handling.)

Pay attention to the functions being called and what the data types are of the return values from those functions.

Also, note that if the form is not valid, you’re not doing anything to handle that situation - like refreshing the page with the form and the errors identified. But that’s a different issue for the moment.

1 Like

so I changed it now and it works, but how can I check if an entry already exists so that every user just can create 1 db entry and overwrite it when using the form again

and another thing is, with the code i’ve written the user was put into the ModelField but in the database there is an option with user_id which is NULL but if I want to set the user Id into the UserField in my model it obviously says that it has to be an user and not an id

heres my code

@login_required(login_url='home:login')
def AccountInfoPrename(request):
        if request.method == 'POST':
            form = AccountInfoPrenameForm(request.POST)
            if form.is_valid():
                account = form.save(commit=False)
                account.user = request.user
                Account.user = account.user
                account.save()


            return redirect('home:profile')
        else:
            form = AccountInfoPrenameForm()
        return render(request,
                  'home/profile.html',
                  {'form': form}

                  )

and my models.py

from django.db import models
from django.contrib.auth.models import User

class Account(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    prename = models.CharField(max_length=20, null=True)
    surname = models.CharField(max_length=40, null=True)
    company = models.CharField(max_length=40, null=True)
    profile_pic = models.CharField(max_length=40, null=True)
    country = models.CharField(max_length=40, null=True)
    packet_premium = models.BooleanField(null=True)
    packet_business = models.BooleanField(null=True)


    def __str__(self):
        return self.user.username


That doesn’t belong in this at all. Account is the name of the class, not a reference to an instance of the class. account is the instance of the class you’re using and is the only place where you need the value set.

A OneToOne field should enforce that requirement. Are you actually seeing multiple rows being created for the same User?

See the docs on ForeignKey fields.

But how can I acces the rest of the Model like the User when the form just includes the Prename

Its difficult to say because there aren’t ids shown, but I’ve created 3 with the same user.

I don’t understand what you’re trying to ask here. What are you trying to do?

Check your database - see if you’ve got one row or three.

I’m trying to set the user value from the model to the user from the form.

Actually there are 3 rows but just the first one from the user has an id set.

If you’re talking about the AccountInfoPrenameForm that you’re using in the AccountInfoPrename view, that form doesn’t have a user field. I’m still not able to understand what you’re trying to do here. Or, to be more specific, what do you think you’re going to accomplish by this line?

Whatever you think it’s going to do for you, it’s not.

In general I want to set the User from the Register Form into my Account Model by putting the request user into my Account.user and saving the Model heres my code for that which isnt working

views.py

def register_view(request):
    if request.user.is_authenticated:
        return redirect('home:profile')
    else:
        form = CreateUserForm

        if request.method == 'POST':
            form = CreateUserForm(request.POST)
            if form.is_valid():
                Account.user = request.user
                Account.save()
                form.save()

                messages.success(request, 'Account wurde erstellt')

                return redirect('home:login')

        context = {'form': form}
        return render(request, 'home/register.html', context)

ERROR:

Internal Server Error: /register/
Traceback (most recent call last):
  File "C:\Users\Finn\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\Finn\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "D:\Developement\Projekte\DivusX\DivusX\StartSite\views.py", line 99, in register_view
    Account.save()
TypeError: save() missing 1 required positional argument: 'self'

Then I made for every Field of the Model a form for saving information for the model in different pages, but there is the problem that the id doesnt show up in the database and that I can create unlimited entrys in the database, but I think the thing with the id is caused by the register view.

NO!
Account is the class, not the instance of the class. You are creating an instance of Account called account. It is account being saved to the database, not Account.

You were a lot closer with your view here - ModelForm isnt working - #30 by FLYAX than you are with this current version posted immediately above.

yeah I already know, the working version is this:

def register_view(request):
    if request.user.is_authenticated:
        return redirect('home:profile')
    else:
        form = CreateUserForm

        if request.method == 'POST':
            form = CreateUserForm(request.POST)
            if form.is_valid():
                form.save()
                account = form.save(commit=False)
                account.user = request.user
                account.save()

                messages.success(request, 'Account wurde erstellt')

                return redirect('home:login')

        context = {'form': form}
        return render(request, 'home/register.html', context)


just changed it to look if my id plugin gets fixed in any way, but still the id is NULL when I submit the form

You’re calling form.save twice here.

ah yes thanks for reminder, but that still doesnt change anything. The id is still NULL