title: Preventing django form to refresh whole page on submit
body: <p>I have a form in Django which is embedded in a bootstrap modal element. The input of the form is a client id which I check if it is in the database. Everything works fine on submit except that in case the client id is not in the database the page gets reloaded and I have to open the modal element again to see the error message.</p>
  
  <p>I tried to simple prevent the page refresh by adding a script to my html:</p>
  
  <pre><code>$('#modalform').on('submit', function (e) {
          e.preventDefault();
      })
  </code></pre>
  
  <p>But this breaks the form behaviour on submit.</p>
  
  <p>The modal div with the form in my home.html looks like this:</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;div class="modal fade" tabindex="-1" role="dialog" id="mymodal" aria-labelledby="myLargeModalLabel"&gt;
      &lt;div class="modal-dialog"&gt;
          &lt;div class="modal-content"&gt;
              &lt;div class="modal-body"&gt;
                  &lt;form action="" method="POST" id="modalform"&gt;
                      {% csrf_token %}
  
                      {% if form.non_field_errors %}
                          &lt;div class="alert alert-danger" role="alert"&gt;
                              {% for error in form.non_field_errors %}
                                  {{ error }}
                              {% endfor %}
                          &lt;/div&gt;
                      {% endif %}
  
                      {% for field in form.visible_fields %}
                          &lt;div class="form-group"&gt;
                              {{ field.label_tag }}
  
                              {% if form.is_bound %}
                                  {% if field.errors %}
                                      {% render_field field class="form-control is-invalid" %}
                                      {% for error in field.errors %}
                                          &lt;div class="invalid-feedback"&gt;
                                              {{ error }}
                                          &lt;/div&gt;
                                      {% endfor %}
  
                                   {% else %}
                                       {% render_field field class="form-control is-valid" %}
                                   {% endif %}
                               {% else %}
                                   {% render_field field  class="form-control" %}
                               {% endif %}
                           &lt;/div&gt;
                       {% endfor %}
  
                  &lt;input class="btn btn-primary" type="submit" value="submit"&gt;
              &lt;/form&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>The view in view.py looks like this:</p>
  
  <pre class="lang-py prettyprint-override"><code>def home(request):
      if request.method == "POST":
          print("POST")
          form = SelectClient(request.POST)
  
          if form.is_valid():
              url = reverse(
                  "client",
                  kwargs={"client_id": form.cleaned_data["client_id"]},
              )
              return HttpResponseRedirect(url)
  
      else:
          form = SelectClient()
          print("GET")
  
      return render(request, "app/home.html", {"form": form})
  </code></pre>
  
  <p>The form looks like this:</p>
  
  <pre class="lang-py prettyprint-override"><code>class SelectClient(forms.Form):
      client_id = forms.CharField(label="Client ID")
  
      def clean_client_id(self):
          data = self.cleaned_data["client_id"]
  
          if Client.objects.filter(client_id=data).exists():
              print("Success!")
          else:
              print("No such client!")
              raise ValidationError(
                  _("No such client!")
              )
  
          return data
  </code></pre>
  
  <p>And urls.py looks like this: </p>
  
  <pre class="lang-py prettyprint-override"><code>urlpatterns = [
      path("", views.home, name="app-home"),
      path(
          "client/&lt;str:client_id&gt;",
          views.client,
          ),
  ]
  </code></pre>
  
  <ol>
  <li><p>Can I achieve that on submit of a client_id which is not in the database the page does not fully reload and just updates the error message without using ajax?</p></li>
  <li><p>If not: How would the added ajax code look like, if I want the desired behaviour?</p></li>
  </ol>
  
  <p>My first idea went to something like this:</p>
  
  <pre><code>$('#modalform').on('submit', function (e) {
          e.preventDefault();
  
          $.ajax({
              type: 'POST',
              url: '/home/',
              data: {
                  client_id: $('#client_id').val(),
                  csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val()
              },
              success: function () {
                  alert("Client found, but what now?!");
              },
              error: function () {
                  alert("Client not found, but what now?!")
              }
          })
  
      })
  </code></pre>