'In Django {{user.username}} and {{request.user.username}} return the wrong username in template

I'm fairly new to programming in general and am working on a Django Web-App. I am using a ChangeUserData form to update a user's account data (I am using the standard django.contrib.auth User model). When a user's attempt to change their username fails because the new username is already in use, the template is displayed again, alongside the relevant error message.

However, the "username" input in the form displays the "new" username, i.e. the one that was rejected for already being in use. I am surprised/confused by this, since in the template I am using {{ request.user.get_username }} to fill in this input. Shouldn't this insert the current user's actual - unchanged - username?

I have also tried {{ user.username }} and {{ user.get_username }} but they yield the same result.

Below are excerpts from the relevant files:

views.py

def MyAccount(request):
    if request.method == 'POST':
        form = forms.ChangeUserData(request.POST, instance=request.user)
        if form.is_valid():
            form.save(commit=True)        
            return redirect('home')
        else:
            return render(request, 'accounts/myAccount.html', { 'form' : form })
    else:
        return render(request, 'accounts/myAccount.html')

myAccount.html

 <input type="text" class="inputLocked" name="username" required autocapitalize="none" value="{{user.get_username}}" id="id_username" readonly>


Solution 1:[1]

You should also send empty ChangeUserData to be filled by user in GET condition, when data is not from POST request.

After, validation failed, you don't need to use render to fully render HttpResponse, here the best choice is to make use of messages[django-doc] framework, which eventually tell user which validation has been failed. But if you have made ChangeUserData form through Form Api, so I assume you don't need to do that, since here you can define error_messages inside forms.

To get current username, try using request.user.username.

Note: Forms in Django requires Form to be the suffix so it must be ChangeUserDataForm not changeUserData

Note: Function based views are generally written in snake_case not PascalCase, since that's the way how class based views work, so it would be better if you change it to my_account from MyAccount.

Try below code:

views.py

def my_account(request):
    if request.method == 'POST':
        form = forms.ChangeUserDataForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save(commit=True)        
            return redirect('home')
    else:
        form=forms.ChangeUserDataForm() #Here empty form for get request.
        return render(request, 'accounts/myAccount.html',{'form':form})

myAccount.html

<input type="text" class="inputLocked" name="username" required autocapitalize="none" value="{{request.user.username}}" id="id_username" readonly>

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 Sunderam Dubey