Запрет формы django для обновления всей страницы при отправке - PullRequest
0 голосов
/ 07 июня 2019

У меня есть форма в Django, которая встроена в модальный элемент начальной загрузки. Ввод формы - это идентификатор клиента, который я проверяю, находится ли он в базе данных. Все работает нормально при отправке, за исключением того, что в случае, если идентификатор клиента отсутствует в базе данных, страница перезагружается, и мне нужно снова открыть модальный элемент, чтобы увидеть сообщение об ошибке.

Я попытался просто предотвратить обновление страницы, добавив скрипт в мой html:

$('#modalform').on('submit', function (e) {
        e.preventDefault();
    })

Но это нарушает поведение формы при отправке.

Модальный div с формой в моем home.html выглядит так:

<div class="modal fade" tabindex="-1" role="dialog" id="mymodal" aria-labelledby="myLargeModalLabel">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-body">
                <form action="" method="POST" id="modalform">
                    {% csrf_token %}

                    {% if form.non_field_errors %}
                        <div class="alert alert-danger" role="alert">
                            {% for error in form.non_field_errors %}
                                {{ error }}
                            {% endfor %}
                        </div>
                    {% endif %}

                    {% for field in form.visible_fields %}
                        <div class="form-group">
                            {{ field.label_tag }}

                            {% if form.is_bound %}
                                {% if field.errors %}
                                    {% render_field field class="form-control is-invalid" %}
                                    {% for error in field.errors %}
                                        <div class="invalid-feedback">
                                            {{ error }}
                                        </div>
                                    {% endfor %}

                                 {% else %}
                                     {% render_field field class="form-control is-valid" %}
                                 {% endif %}
                             {% else %}
                                 {% render_field field  class="form-control" %}
                             {% endif %}
                         </div>
                     {% endfor %}

                <input class="btn btn-primary" type="submit" value="submit">
            </form>
        </div>
    </div>
</div>

Вид в view.py выглядит следующим образом:

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

Форма выглядит так:

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

И urls.py выглядит так:

urlpatterns = [
    path("", views.home, name="app-home"),
    path(
        "client/<str:client_id>",
        views.client,
        ),
]
  1. Можно ли добиться этого при отправке client_id, которого нет в базе данных, страница не полностью перезагружается и просто обновляет сообщение об ошибке без использования ajax?

  2. Если нет: как будет выглядеть добавленный код Ajax, если я хочу нужного поведения?

Моя первая идея пришла к чему-то вроде этого:

$('#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?!")
            }
        })

    })

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Вы хотите проверить, есть ли ошибки формы (вы могли бы сделать определенное поле) и всплыть модальные, если есть

<script>
    {% if form.errors %}
        document.getElementById("mymodal").showModal(); 
    {% endif %}
</script>
0 голосов
/ 07 июня 2019

Поскольку мне было трудно работать с формами Django в этом случае, я решил проблему более явно.

Моя новая test_form форма:

<form id="test_form">
    {% csrf_token %}
    <div class="form-group">
        <label for="client_id">Client ID:</label>
        <input class="form-control" id="client_id" placeholder="Client ID" />
        <div class="form-text text-danger" id="form-error"></div>
    </div>
    <input class="btn btn-primary" type="submit" value="submit">
</form>

Мой Javascript для новой test_form формы:

$('#test_form').on('submit', function (e) {
        e.preventDefault();

        $.ajax({
            type: 'POST',
            url: 'ajax/testform/',
            data: {
                client_id: $('#client_id').val(),
                csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val()
            },
            success: function (data) {

                console.log(data["status"])
                if (data["status"] == "valid") {
                    window.location.href = "/client"
                }
                if (data["status"] == "invalid") {
                    $("#form-error").html(data["message"]);
                    $("#client_id").addClass("is-invalid")
                }
            },
            error: function () {
                alert("Error!")
            }
        })

    })

И новый testform вид:

def testform(request):
    if request.method == "POST":
        form = SelectClient(request.POST)

        if request.is_ajax():
            if form.is_valid():
                data = {"status": "valid", "client_id": form.cleaned_data["client_id"]}

            else:
                data = {
                    "status": "invalid",
                    "client_id": form.data["client_id"],
                    "message": form.errors["client_id"],
                }
        else:
            data = {"message": "not an ajax call"}
        return JsonResponse(data)

Что-нибудь против этого решения? Это хорошая практика?

...