skip to Main Content

may someone tell me how to avoid to have the error message shown 2 times?
I’d like to keep the top error message, but on red.

enter image description here

https://files.slack.com/files-pri/T07EFKXHR-F058SR427RA/image.png

html:

<form hx-post="{{ request.path }}" class="modal-content p-4" enctype="multipart/form-data">
<div class="modal-header">
    <h5 class="modal-title">Ingresa tu usuario y clave</h5>
  </div>
    {% csrf_token %}

    {{ login_form.as_p }}
    {% if login_form.errors %}
        <ol class="">
            {% for field_errors in login_form.errors.values %}
                {% for error in field_errors %}
                    <li class="text-danger"><strong>{{ error|escape }}</strong></li>
                {% endfor %}
            {% endfor %}
        </ol>
    {% endif %}

<div class="modal-footer">
    <button type="submit" class="btn btn-primary">Ingresar</button>
  </div>

</form> 

form.py:

class LoginForm(AuthenticationForm):
    username = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Nombre de usuario'}))
    password = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Contraseña'}))

view.py:

def login_view(request):
    if request.method == 'POST':
        login_form = LoginForm(request, data=request.POST)
        print("### Request is post")

        if login_form.is_valid():
            print("### Request is VALID")
            username = login_form.cleaned_data.get('username')
            password = login_form.cleaned_data.get('password')
            print("User name", username, "type: ", type(username))
            print("Pass", password, "type: ", type(password))
            user = authenticate(request, username=username, password=password)
            if user is not None:
                login(request, user, backend='django.contrib.auth.backends.ModelBackend')
                return HttpResponse(status=204, headers={'HX-Trigger': 'user_logged_in'})
        else:
            return render(request=request, template_name="account/email/login_form.html",
                          context={'login_form': login_form, 'errors': login_form.errors})

    else:
        login_form = LoginForm(request)
        context = {
            "login_form": login_form,
        }
        return render(request=request, template_name="account/email/login_form.html",
                      context={'login_form': login_form, 'errors': login_form.errors})

UPDATE 1:

not rendering explicitly the errors in HTML, leaves me without errors at all.

May be something related to HTMX usage?

enter image description here

<form hx-post="{{ request.path }}" class="modal-content p-4" enctype="multipart/form-data">
<div class="modal-header">
    <h5 class="modal-title">Ingresa tu usuario y clave</h5>
  </div>
    {% csrf_token %}

    {{ login_form.as_p }}


<div class="modal-footer">
    <button type="submit" class="btn btn-primary">Ingresar</button>
  </div>

</form>

image:

2

Answers


  1. Django renders the errors by default within {{ login_form.as_p }}. It would be quite error-prone if the errors would need to be rendered explicitly, as it’s easy to forget about it.

    So there are the errors rendered once, and the second time they are rendered becuase you do that explicitly yourself via inside the block {% if login_form.errors %} ... {% endif %}

    Login or Signup to reply.
  2. To display an error only once when a user enters invalid information on form submission in Django, you can make use of Django’s form validation and handle the error display in your template. Here’s a general approach:

    Form Validation: In your Django form, define the validation rules for each field using the clean_() method. Perform the necessary validation checks, such as checking for valid input, uniqueness, or any other custom requirements.

    Error Handling in View: In your view function, after validating the form using form.is_valid(), you can check if the form is invalid. If it is, you can add an error message to the form instance using form.add_error(fieldname, error_message). This will associate the error message with the corresponding field.

    Template Rendering: In your template, when rendering the form fields, you can check if the field has any errors associated with it using form.fieldname.errors. If errors exist, you can display them using appropriate HTML markup and styling.

    Here’s an example of how it can be implemented:

    python

    # views.py
    from django.shortcuts import render
    from .forms import MyForm
    
    def my_view(request):
        if request.method == 'POST':
            form = MyForm(request.POST)
            if form.is_valid():
                # Process the valid form data
                return render(request, 'success.html')
            else:
                # Handle form errors
                form.add_error(None, "Please correct the errors below.")
        else:
            form = MyForm()
        
        return render(request, 'my_template.html', {'form': form})
    

    html

    <!-- my_template.html -->
    <form method="POST" action="">
        {% csrf_token %}
        {% if form.non_field_errors %}
            <div class="error">
                {{ form.non_field_errors }}
            </div>
        {% endif %}
    
        <div class="form-group">
            {{ form.fieldname }}
            {% if form.fieldname.errors %}
                <div class="error">
                    {{ form.fieldname.errors }}
                </div>
            {% endif %}
        </div>
    
        <!-- Other form fields -->
    
        <button type="submit">Submit</button>
    </form>
    

    In this example, the form.non_field_errors is used to display a general error message at the form level, and form.fieldname.errors is used to display errors specific to each field.

    By using this approach, the errors will be displayed to the user only once, making the form submission experience more user-friendly.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search