User.username показывает неверную информацию об имени вошедшего в систему пользователя

views.py

def 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, f'Account has been 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/profile.html', context)

users/profile.html

  <h1>{{ user.username }}</h1>
  <h2>{{ user.email }}</h2>
  <img src="{{ user.profile.image.url }}" width="200" style="border: 3px solid black;">
  <form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ u_form }}
    {{ p_form }}
    <button type="submit">Update profile</button>
  </form>

models.py

from django.contrib.auth.models import User


class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')

    def __str__(self):
        return f'{self.user.username} Profile'

    def save(self, *args, **kwargs):
        super().save(*args, **kwargs)

        img = Image.open(self.image.path)

        if img.height > 300 or img.width > 300:
            output_size = (300, 300)
            img.thumbnail(output_size)
            img.save(self.image.path)

forms.py

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


class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField()

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


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

Когда я отправляю форму, которая не проходит валидацию, например, такое имя пользователя уже существует, то {{user.username}} все равно изменяется на это неправильное имя пользователя, но в базе данных ничего не меняется, так как форма не проходит валидацию, и это нормально, но почему {{user.username}} становится равным этому невалидированному значению?

Я ожидал, что {{user.username }} останется таким же, как в базе данных и как данные вошедшего пользователя

Просто уберите instance=request.user из форм на POST запросы:

def profile(request):
    if request.method == 'POST':
        u_form = UserUpdateForm(request.POST)
        p_form = ProfileUpdateForm(request.POST, request.FILES)
        ...

Когда при постинге вы задаете request.POST в качестве данных формы, эти данные содержат неправильное/недействительное имя, которое вы пытаетесь задать. Поскольку вы не перестраиваете форму, данные остаются неверными и отображаются таким образом.

Исправляется только после того, как вы отправите GET запрос и восстановите форму с правильными данными.

Вернуться на верх