Struggling with two 1:1 models in a view and saving

Hi. I’m really just getting started with Django and am struggling with something. I want to create a view and render a template that allows a user to register an account. There is a model for the account info and a model for user profile. They “should” be related in a 1:1 by the username/user_id. The template loads fine but when I try to POST i get an Integrity Error - NOT NULL constraint failed: user_profile.user_id_id. I assume this has to do with how I am handling my two models in my view and their instances? But I need help! thanks!

Here are my code snippets:

models.py



class UserProfile(models.Model):

    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$', message="format as +999999999")

    first_name = models.CharField('First Name', max_length=50, blank=False)
    middle_name = models.CharField(_("Middle Name"), max_length=50, blank=True)
    last_name = models.CharField(_("Last Name"), max_length=50, blank=False)
    date_of_birth = models.DateField(
        _("Date of Birth"), auto_now=False, auto_now_add=False)
    gender = models.CharField(_("Gender"), max_length=8, choices=gender_choices, null=True)
    employee_id = models.IntegerField(_("Employee ID"))
    user_avatar = models.ImageField(_("Avatar"), upload_to='uploads/', blank=True, default="")
    mobile_number = models.CharField(
        max_length=17, blank=True, validators=[phone_regex])
    user_id = models.OneToOneField(CustomUserAccount, on_delete=models.PROTECT, default="")

    class Meta:
        db_table = "user_profile"
class CustomUserAccount(AbstractUser):
    username = models.CharField(
        'Username', max_length=50, blank=False, unique=True)
    first_name = models.CharField('First Name', max_length=50, blank=False)
    last_name = models.CharField('Last Name', max_length=50, blank=False)
    email = models.EmailField('Email', max_length=100, blank=False)
    password = models.CharField('Password', max_length=200, blank=False)

    def __str__(self):
        return self.username

    class Meta:
        db_table = "user_account"

forms.py

class UserAccount(forms.ModelForm):
   class Meta: 
       model = CustomUserAccount
       exclude = ['is_active','is_superuser','user_permissions','is_staff','groups','date_joined', 'last_login']
       
   

class UserProfile(forms.ModelForm):
   class Meta:
       model = UserProfile
       exclude = ['user_id']

views.py

def RegisterView(request):

    if request.method == 'POST':
        profile_form = UserAccount(request.POST)
        print(profile_form)
        user_form = UserProfile(request.POST)
        print(user_form)
        if all([profile_form.is_valid(), user_form.is_valid()]):

            account = user_form.save()
            profile = profile_form.save(commit=False)
            profile.user_id = account
            profile.save()

            return redirect('registration/profile_success.html')
    else:
        profile_form = UserAccount()
        user_form = UserProfile()

    context = {
        "profile_form": profile_form,
        "user_form": user_form
    }
    return render(request, 'registration/signup.html', context=context)


Welcome @skeetno1 !

Do you have these names reversed? It seems to me that UserAccount should be assigned to the name user_form, and that UserProfile should be assigned to profile_form.

Additionally, when using multiple forms on the same page, you need to use the prefix attribute on the forms. Each form should have a unique prefix, and that prefix needs to be used with both the default creation and the binding operation.
E.g., profile_form = UserProfile(prefix="profile") and profile_form = UserProfile(request.POST, prefix="profile")

that looks like it worked. You’re awesome! Thank you!