Skip to content
Advertisement

reset form to initial data in invalid_form and display error in Django

I have a profile form that shows email, user name and first name. user only allowed to change first name field and the others are read only, if user change HTML value in email and username then submit it, it returns error but fill the fields with invalid value entered. I tried create a new instance of form and render it but it no longer shows the error. The thing I want is to reset invalid data then display the error.

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()
        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 page

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

Advertisement

Answer

After a few searches I found that I can address my issue by adding disabled=True attribute to my fields so if user try to change it database will ignore change and returns the initial value as it said in Django documentation

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'}))
Advertisement