'Django Form not Saving The field I added

I am following a Django tutorial on Youtube, I added a bio field in the UserUpdateForm. There is a slot for me to edit the bio on change_profile.html but when I press the update button it updates everything else except for the bio.

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile

class UserRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField()
    # What I added
    bio = forms.CharField(required=False)

    class Meta:
        model = User
        fields = ['username', 'email', 'bio']

class ProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['image']

The function that saves the forms

@login_required
def change_profile(request):
    if request.method == 'POST':
        u_form = UserUpdateForm(request.POST, instance=request.user)
        p_form = ProfileUpdateForm(request.POST, request.FILES, instance=request.user.profile)
        if u_form.is_valid() and p_form.is_valid():
            u_form.save()
            p_form.save()
            messages.success(request, 'Profile Updated')
            return redirect('profile')
    else:
        u_form = UserUpdateForm(instance=request.user)
        p_form = ProfileUpdateForm(instance=request.user.profile)
    context = {
        'u_form' : u_form,
        'p_form' : p_form
    }
    return render(request, 'users/change_profile.html', context)

The change_profile.html

{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block title %}Change Profile{% endblock title %}
{% block content %}
    <div class="content-section">
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <fieldset class="form-group">
                <legend class="border-bottom mb-4">Edit Profile</legend>
                {{ u_form|crispy }}
                {{ p_form|crispy }}
            </fieldset>
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit">Update</button>
            </div>
        </form>
    </div>
{% endblock content %}

And the profile.html

{% extends "blog/base.html" %}
{% block title %}Profile{% endblock title %}
{% block content %}
    <div class="content-section">
        <div class="media">
            <img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
            <div class="media-body">
                <h2 class="account-heading">{{ user.username }}</h2>
                <p class="text-secondary">{{ user.email }}</p>
                <p class="article-content">{{ user.bio }}</p>
            </div>
        </div>
        <a class="ml-2" href="{% url 'change_profile' %}">Edit Profile</a>
{% endblock content %}


Solution 1:[1]

You could have simply override the the User model and add your custom fields, then you don't need to add extra fields in your form. Check this example:

from django.contrib.auth.models import User


class UserProfile(models.Model):

    user = models.OneToOneField(User)
    bio = models.TextField()

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

Make sure you add mention your custom User model in settings:

AUTH_USER_MODEL ='your_app.UserProfile'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Shahid Tariq