Search code examples
pythondjangodjango-modelsdjango-formsdjango-users

How can I allow users to edit their profiles in Django?


I have a model in models.py like this:

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.DO_NOTHING)
    phone_number = models.CharField(max_length=50, default='')
    Birthday = models.CharField(max_length=50, default='')
    city = models.CharField(max_length=50, default='')
    school = models.CharField(max_length=100, default='')
    course = models.CharField(max_length=50, default='')

I want to allow my users to make edits, so I made a function like this in my views.py:

    if request.method == 'POST':
        profil = UserProfile.objects.get(user=request.user)
        profil.phone_number = models.CharField(max_length=50, default='')
        profil.Birthday = models.CharField(max_length=50, default='')
        profil.city = models.CharField(max_length=50, default='')
        profil.school = models.CharField(max_length=100, default='')
        profil.course = models.CharField(max_length=50, default='')
        
        profil.save()
        
        return redirect('profile')  
 
    return render(request, 'edit_profile.html')

My template is:

<form action="." method="post">
        {% csrf_token %}    
        Phone Number:
        <input type="text" name="phone_number" value="{{  profil.phone_number }}" /><br />
        Birthday:
        <input type="text" name="Birthday" value="{{  profil.Birthday }}" /><br />
    
        city:
        <input type="text" name="city" value="{{  profil.city }}" /><br />
        school:
        <input type="text" name="school" value="{{  profil.school }}" /><br />
    
        course:
        <input type="text" name="course" value="{{  profil.course }}" /><br />
       
        <input type="submit" value="Save Changes" name="save" />
        <input type="reset" value="Cancel" name="cancel" />
        <br/>
    </form>

I do not know why, but after filling the form I get an error saying page not found. And if I check the existing user profile nothing got updated. Help please.


Solution

  • you have an error

    profil = UserProfile.objects.get(user=request.user)
    profil.phone_number = models.CharField(max_length=50, default='')
    

    you get an UserProfile object and then instead of saving str into phone_number you try to save an object models.CharField. use ModelForm to achieve what you need.

    class UserProfileForm(forms.ModelForm):
        class Meta:
            model = UserProfile
            fields = '__all__'
    

    then in your view you can use:

    userprofile_form = UserProfileForm(request.POST if request.POST else None, instance = UserProfile.objects.get(user=request.user))
    if request.method == 'POST':
        if form.is_valid():
            form.save()     
            return redirect('profile')  
    
    return render(request, 'edit_profile.html', context={'userprofile_form': userprofile_form)
    

    and in html use:

    <form action="." method="post">
        {% csrf_token %}    
        Phone Number: {{ userprofile_form.phone_number }}
        Birthday: {{ userprofile_form.Birthday }}
        city: {{ userprofile_form.city }}
        school: {{ userprofile_form.school }}
        course: {{ userprofile_form.course }}           
        <input type="submit" value="Save Changes" name="save" />
        <input type="reset" value="Cancel" name="cancel" />
        <br/>
    </form>
    

    or just

     <form action="." method="post">
         {% csrf_token %}    
         {{ userprofile_form }}           
         <input type="submit" value="Save Changes" name="save" />
         <input type="reset" value="Cancel" name="cancel" />
         <br/>
     </form>
    

    if you want to use upload files, don't forget to put your files into form you can do it UserProfileForm(request.POST, request.FILES, instance = UserProfile.objects.get(user=request.user)) and in html you need to put <form enctype="multipart/form-data" method="post" action="...">