【问题标题】:Online waiting: django submit form and display result in same page在线等待:django提交表单并在同一页面显示结果
【发布时间】:2022-01-02 02:53:13
【问题描述】:

我有一个紧急任务来制作一个网页,允许用户输入一些数据,后端进行一些计算,结果需要显示在输入字段下方的同一页面中(如机票在线价格检查) .

我是 django 和 html 的新手。下面是我的第一个简单的在线计算器测试网页,试图弄清楚如何制作这样的网络服务。

我发现一个问题,当点击“提交”按钮时,它往往会跳转到一个新的网页或一个新的网页标签。这不是我想要的。一旦用户输入数据并单击“提交”按钮,我希望页面上的“结果”字段直接显示结果(即仅部分更新此字段)而不刷新/跳转到新页面。我也希望用户输入数据在点击“提交”后保留在同一页面中。

我看到可能有几种不同的方式来完成这项工作,iframe/AJAX。但是,我已经搜索/尝试了几天的答案和解决方案,但没有一个答案真正适用于这个非常基本的简单问题!

html:

<form method="POST">
    {% csrf_token %}
    <div>
      <label>num_1:</label>
      <input type="text" name="num_1" value="1" placeholder="Enter value" />
    </div>
    <div>
      <label>num_2:</label>
      <input type="text" name="num_2" value="2" placeholder="Enter value" />
    </div>
    <br />
    <div>{{ result }}</div>
    <button type="submit">Submit</button>
</form>

view.py

def post_list(request):
    result = 0
    if request.method == "POST":
        num1 = request.POST.get('num_1')
        num2 = request.POST.get('num_2')
        result = int(num1) + int(num2)
        print(request.POST)
        print(result)

    context = {
        'result': result
    }
    return render(request, 'blog/post_list.html', context)

【问题讨论】:

    标签: html jquery django ajax forms


    【解决方案1】:

    我建议看一下htmx.org,它使这变得非常简单,无需编写任何实际的 JS。

    你的例子:

    (1) 您将 htmx JS(大约只有 10k)添加到您的 HTML 中,并使用 hx-posthx-target 来触发表单上的 ajax 调用。有了这些,表单将触发一个 AJAX 请求,hx-target 告诉 htmx 接受响应(您希望它只是计算的结果)并将其放入 div 而不刷新整个页面。 有关更多详细信息,请参阅docs。 还要注意我给了包含结果的 div 一个id。 您需要将 hx-post="{% url 'blog:post_list' %}" 替换为您视图的正确名称(我们不知道,因为您没有发布您的 urls.py)。

    <html>
        <body>
            <form method="POST" hx-post="{% url 'blog:post_list' %}" hx-target="#result">
                {% csrf_token %}
                <div>
                <label>num_1:</label>
                <input type="text" name="num_1" value="1" placeholder="Enter value" />
                </div>
                <div>
                <label>num_2:</label>
                <input type="text" name="num_2" value="2" placeholder="Enter value" />
                </div>
                <br />
                <div id="result">{{ result }}</div>
                <button type="submit">Submit</button>
            </form>
            <script src="https://unpkg.com/htmx.org@1.6.1"></script>
        </body>
    </html>
    

    (2) 在您看来,您可以通过检查标头来确定请求是否是来自 htmx 的 AJAX 请求,在这种情况下您只想返回结果。有更简单或优雅的方法可以做到这一点(例如检查django-htmx,但只是为了保持简单:

    from django.http.response import HttpResponse
    from django.shortcuts import render
    
    # Create your views here.
    def post_list(request):
        result = 0
        if request.method == "POST":
            num1 = request.POST.get('num_1')
            num2 = request.POST.get('num_2')
            result = int(num1) + int(num2)
    
        if request.headers.get('Hx-Request') == 'true':
            # return only the result to be replaced
            return HttpResponse(str(result))
        else:
            return render(request, 'blog/post_list.html', {'result': result})
    

    【讨论】:

    • 感谢您的帮助。但是,它报告“未找到:/favicon.ico”和“未找到:/post_list”。哪里错了?
    • 道歉-我的回答疏忽了。对于hx-post="/post_list",您应该将其替换为您在urls.py 中定义的视图的URL。如果这被称为post_list(就像你的视图函数),那么像hx-post="{% url 'blog:post_list' %}" 这样的东西应该可以解决问题。 favicon.ico 错误与此问题无关,无论如何都会出现,这只是意味着您没有为您的网站设置书签图标。
    • 进行此更改后,它会报告另一个错误:“异常值:'blog' 不是已注册的命名空间”
    • 这就是我的 url.py 的设置方式: from django.urls import path from . import views urlpatterns = [ path('', views.post_list, name='post_list') ] 基本设置遵循本教程:tutorial.djangogirls.org/en/django_urls
    • 在我对命名空间的 mysite/urls 进行更改后 -> urlpatterns = [ path('admin/', admin.site.urls), # path('', include('blog.urls' )), path('', include(('blog.urls','blog'),namespace='blog')) ] 有效!!现在我正在切换到关于在线定价的项目。我有两个结果字段需要显示,而不是一个。输入两个 hx 目标?比如:
      hx-target="#result_2"> ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多