save form data with one to one relationship in django

Viewed 291

I have one to one relationship with the Django User model and custom Profile model. I trying to save user and profile data at the same time when the user is registered. But the problem is the data of the profile model is not validating and data is not saving in the database here is code

model.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    picture = models.ImageField(upload_to = 'profile_pictures')
    Join_as = models.CharField(choices=USER_CHOICES, max_length=70)
    date = models.DateField(auto_now_add=True)

form.py

class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['picture','Join_as']
        labels = {
            'picture':'Upload Profile Picture'
        }
        widgets = {
            'Join_as':forms.Select(attrs={'class':'form-select'}),
            }

view.py

def rigister(request):
    if request.method == 'POST':
        user_form = UserCreationForm(request.POST)
        profile_form = ProfileForm(request.POST, request.FILES)
        if user_form.is_valid() and profile_form.is_valid():
            user_form.save()
            profile_form.save()
        return HttpResponseRedirect('/')
    else:
        user_form = UserCreationForm()
        profile_form = ProfileForm()
    contaxt = {'user_form':user_form,'profile_form':profile_form}
    return render(request, 'registration/register.html', contaxt)

register.html

<form action="" method="POST" enctype='multipart/form-data'>
    {% csrf_token %}
    <div class="row row-cols-2">
        {% for user in user_form  %}
        <div class="col">
            {{user.label_tag}} {{user}} {{user.errors|striptags}}
        </div>
        {% endfor %}
        {% for profile in profile_form %}
        <div class="col">
            {{profile.label_tag}} {{profile}} {{profile|striptags}}
        </div>
        {% endfor %}
    </div>
    <input type="submit" value="Register" class="btn btn-success">
</form>
1 Answers

You can wor with the object saved by the user_form as .user of the instance wrapped in the profile_form:

def rigister(request):
    if request.method == 'POST':
        user_form = UserCreationForm(request.POST)
        profile_form = ProfileForm(request.POST, request.FILES)
        if user_form.is_valid() and profile_form.is_valid():
            user = user_form.save()
            profile_form.instance.user = user
            profile_form.save()
            return HttpResponseRedirect('/')
    else:
        user_form = UserCreationForm()
        profile_form = ProfileForm()
    contaxt = {'user_form':user_form,'profile_form':profile_form}
    return render(request, 'registration/register.html', contaxt)

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

Related