防止Django表单在提交时刷新整个页面

时间:2019-06-07 10:04:27

标签: jquery ajax django django-forms bootstrap-modal

我在Django中有一个表单,该表单嵌入在引导程序模式元素中。表单的输入是客户端ID,我检查它是否在数据库中。提交时一切正常,除非万一客户端ID不在数据库中,否则页面将重新加载,我必须再次打开modal元素才能看到错误消息。

我试图通过向我的html中添加脚本来简单地防止页面刷新:

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

但这会破坏提交时的表单行为。

我的home.html中带有表单的模式div看起来像这样:

<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 个答案:

答案 0 :(得分:1)

您要检查是否存在表单错误(可以在特定字段中输入),并在出现模式错误时弹出模式

<script>
    {% if form.errors %}
        document.getElementById("mymodal").showModal(); 
    {% endif %}
</script>

答案 1 :(得分:0)

由于在这种情况下我很难使用Django Forms,因此我更明确地解决了这个问题。

我新的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>

新的test_form格式的我的Javascript:

$('#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)

反对这种解决方案吗?这是好的做法吗?