首页 > 解决方案 > Ajax 使用 preventDefault() 重定向到 url

问题描述

我正在将 Django 用于允许您搜索和保存食谱的应用程序。我正在尝试在搜索结果页面上创建一个表单,该表单允许您单击“保存”并为数据库创建一个对象,而无需重新加载页面。在当前设置中,当我单击带有 id="add_form" 的表单的“保存”按钮时,即使我包含了 preventDefault(),我也会被重定向到新的 url (add/)。

我认为这是由于我包含了表单 action={%url 'add' %} 但是,我尝试删除表单操作,但这给了我一个 multiValueDictKeyError for raw_input = request.POST['ingredients'] 所以我想它调用了不正确的视图函数views.recipes 而不是views.add。我已经阅读了其他一些明确声明表单操作的 ajax 指南,所以我认为这将有助于调用不正确的视图函数。

视图.py

def recipes(request):
    if request.method == 'POST':
        # check for dietary restrictions
        restrictions = request.POST.getlist('restrictions')
        # format input ingredients
        raw_input = request.POST['ingredients']

    ...

    return render(request, 'recipes/recipes.html', {'results': results})
    else:
    return render(request, 'recipes/recipes.html', {'error': 'Please search for a recipe'})

@csrf_protect
def add(request):
    if request.method == 'POST':
        title = request.POST['title']
        image = request.POST['image']
        source = request.POST['source']
        user = request.user
        try:
            recipe = Recipe.objects.get(image=image, title=title, source=source)
        except ObjectDoesNotExist:
            recipe = Recipe.objects.create(image=image, title=title, source=source)
        finally:
            recipe.users.add(user)
            recipe.save()

    return JsonResponse({'success': True})
else:
    return JsonResponse({'success': False})

网址.py

urlpatterns = [
    path('add/', views.add, name='add'),
    path('', views.recipes, name='recipes'),
 ]

.html 文件

{% block content %}
...
{% if user.is_authenticated %}
<form action="{% url 'add' %}" id="add_form" method="POST">
    {% csrf_token %}
    <input type="hidden" id="image" name="image" value="{{ result.image }}">
     <input type="hidden" id="title" name="title" value="{{ result.title }}">
     <input type="hidden" id="source" name="source" value="{{ result.source }}">

     <button type="submit" name="recipe" class="btn btn-sm btn-outline-secondary">Save</button>
</form>
{% endif %}
{%  endblock %}


{% block javascript %}

<script type="text/javascript">

$(document).ready(function() {
$("#add_form").on('submit', function(e) {
    e.preventDefault();
    console.log( "form submitted");
    $.ajax({
        type:'POST',
        async: 'false',
        cache: 'false',
        url:'{% url 'add' %}',
        data:{
            image:$('#image').val(),
            title:$('#title').val(),
            source:$('#source').val(),
        },
        success:function(){
            alert("Saved Recipe")
        }
    })
 })
 })

</script>

我希望对保存按钮的任何点击都保持在同一页面上而无需重新加载并调用views.add,它将保存/创建一个对象到数据库

标签: djangoajax

解决方案


将网址更改为$(this).attr('action'). 它将自动从表单中获取 url,而不是在进行 ajax 调用时再次显式定义它。

$.ajax({
        type:'POST',
        async: 'false',
        cache: 'false',
        url: $(this).attr('action'),,
        data:{
            image:$('#image').val(),
            title:$('#title').val(),
            source:$('#source').val(),
        },
        success:function(){
            alert("Saved Recipe")
        }
    })

推荐阅读