Сброс формы к исходным данным в invalid_form и отображение ошибки в Django

У меня есть форма профиля, которая показывает email, user name и first name. Пользователю разрешено изменять только поле имя пользователя, остальные поля доступны только для чтения, если пользователь изменит HTML значение в email и имя пользователя, а затем отправит форму, она вернет ошибку, но заполнит поля недействительным введенным значением. Я попробовал создать новый экземпляр формы и отправить его, но он больше не показывает ошибку. Я хочу сбросить недопустимые данные, а затем вывести ошибку.

forms.py

class UserEditForm(forms.ModelForm):

    email = forms.EmailField(
        label='Account email (can not be changed)', max_length=200, widget=forms.TextInput(
        attrs={'class': 'form-control mb-3', 'placeholder': 'email', 'id': 'form-email', 'readonly': 'readonly'}))

    user_name = forms.CharField(
        label='Username', min_length=4, max_length=50, widget=forms.TextInput(
        attrs={'class': 'form-control mb-3', 'placeholder': 'Username', 'id': 'form-username', 'readonly': 'readonly'}))

    first_name = forms.CharField(
        label='First name', min_length=4, max_length=50, widget=forms.TextInput(
        attrs={'class': 'form-control mb-3', 'placeholder': 'Firstname', 'id': 'form-firstname'}))

    class Meta:
        model = UserBase
        fields = ('email', 'user_name', 'first_name',)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['user_name'].required = True
        self.fields['email'].required = True
    
    def clean_user_name(self):
        username = self.cleaned_data['user_name'] 
        if username != self.instance.user_name:
            raise forms.ValidationError('Sorry, you can not change your username')
        return username
    
    def clean_email(self):
        email = self.cleaned_data['email']
        if email != self.instance.email:
            raise forms.ValidationError('Sorry, you can not change your email')
        return email

views.py

class ChangeUserDetail(SuccessMessageMixin, LoginRequiredMixin, FormView):
    template_name = 'accounts/user/default_form.html'
    success_url = reverse_lazy('accounts:dashboard')
    success_message = "Username changed successfully"
    form_class = UserEditForm


    def get_form(self, form_class=form_class):
        return form_class(instance = self.request.user, **self.get_form_kwargs())

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        data = request.POST.copy()
        if form.is_valid():
            return self.form_valid(form)
        else:
            form = self.form_class(instance=self.request.user)
            return self.form_invalid(form)

    def form_valid(self, form):
        user = form.save()
        return super().form_valid(form)

    def form_invalid(self, form):
        return super().form_invalid(form)

html страница

<div class="row">
    <div class="col-md-6">
        {% if form.errors %}
            <div class="alert alert-danger" role="alert">
                {{form.errors}}
            </div>
        {% endif %}
        <form method="post">
            {%csrf_token%}
            {{form|crispy}}
            <div class="form-group">
                <button class="btn btn-outline-info" type="submit">{{title}}</button>
            </div>
        </form>
    </div>
</div>

После нескольких поисков я обнаружил, что могу решить проблему, добавив атрибут disabled=True к моим полям, так что если пользователь попытается изменить его, база данных проигнорирует изменение и вернет первоначальное значение, как сказано в Django документации

class UserEditForm(forms.ModelForm):

    email = forms.EmailField(
        label='Account email (can not be changed)', 
        max_length=200,
        disabled=True, 
        widget=forms.TextInput(
        attrs={'class': 'form-control mb-3', 'placeholder': 'email', 'id': 
        'form-email', 'readonly': 'readonly'}))

    user_name = forms.CharField(
        label='Username', 
        disabled=True,
        min_length=4, 
        max_length=50,
        widget=forms.TextInput(
        attrs={'class': 'form-control mb-3', 'placeholder': 'Username', 'id': 
        'form-username', 'readonly': 'readonly'}))
Вернуться на верх