【问题标题】:Rendering a ModelForm within a Modal & Handling Errors在模态框内渲染 ModelForm 并处理错误
【发布时间】:2016-11-01 21:06:34
【问题描述】:

我有一个视图 item_list_view,它通过呈现模板 mainlist.html 来响应 GET 请求。该模板呈现项目列表以及编辑这些项目的链接:

#mainlist.html
{% for item in items %}
    <a class='edit-link' href='#' data-form="{% url items:itemform %}?i={{item.id}}">
        Edit
    </a>
{% endfor %}

<!-- later in mainlist.html -->
<div class='modal fade' tabindex="-1" role="dialog" id='itemFormModal' style='display:none;'>
</div>

当点击编辑链接时,模态框会使用相应的data-form 属性加载内容,然后显示模态框:

$(".edit-link").click(function(ev){ 
    ev.preventDefault(); 
    var url = $(this).data("form"); 
    $("#itemFormModal").load(url, function() { 
        $(this).modal('show'); 
    });
    return false; //prevent click propogation
});

此时,模态框以适当的 ModelForm 显示,并且该表单具有类 item-form。我们通过 ajax 提交表单:

$(".item-form").on('submit', function() {
    $.ajax({
        type: $(this).attr('method'),
        url: this.action,
        data: $(this).serialize(),
        context: this,
        success: function(data, status) {
            $('#itemFormModal').html(data);
        }
    });
    return false;
});

如果表单提交时包含有效数据,则此方法可以正常工作。成功提交表单后,用户将被重定向回列表视图以及成功消息。

如果表单存在错误,我希望在原始模式中使用这些错误重新呈现表单。但是,现在如果我提交一个有错误的表单,我的浏览器会直接转到表单出现错误的操作 URL。

如何将出现错误的 ModelForm 重新加载到此模式中而不是被重定向?


编辑:当点击编辑链接时,此视图:

def litem_create_edit_view(request):
    #Displays a ModelForm for an Item object 
    #if an "instance" is passed via the url, that 
    #instance is loaded into the ModelForm for editing
    instance_id = request.GET.get('instance', None)
    if instance_id is not None:
        instance = Item.objects.get(id=instance_id)
    else:
        instance = None

    if request.method == 'POST':
        form = ItemForm(request.POST, instance=instance)
        if form.is_valid():
            newitem = form.save()
            messages.add_message(request, messages.SUCCESS, "Item saved!")
            return redirect("items:mainlist")

    else:
        form = LeadForm(instance=instance)

    return render(request, "leads/leadform.html", {'form':form, 'instance':instance})

在模态框内渲染此模板:

<div class='modal-dialog modal-lg'>
  <div class='modal-content'>
    {% if instance %}
    <form method="post" class='lead-form' action="{% url 'leads:leadform' %}?instance={{instance.id}}">
    {% else %}
    <form method="post" class='lead-form' action="{% url 'leads:leadform' %}">
    {% endif %}
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">×</button>
        {% if instance %}
        <h3>Editing Item</h3>
        {% else %}
        <h3>Add Item</h3>
        {% endif %}
      </div>
      <div class="modal-body">
           {% csrf_token %}
           {{ form|crispy }}
      </div>
      <div class="modal-footer">
           <button type='submit' class='btn btn-primary'>Save</button>
           <button type='button' class='btn btn-default' data-dismiss='modal'>Close</button>
      </div>
    </form>
  </div>
</div>

【问题讨论】:

    标签: jquery django twitter-bootstrap django-forms


    【解决方案1】:

    在您看来,请使用以下内容:

    foos  = Foo.objects.all() # or any other model data you want to return
    data = serializers.serialize('json', foos) # serialize it
    

    并返回 JSON 而不是模板:

    return HttpResponse(data, content_type='application/json')
    

    所以这样你就可以留在同一个 div 中而不会被重定向,只有数据 被消费和渲染。

    【讨论】:

    • 有没有办法返回一个渲染的模板而不是 JSON?单击编辑链接时向{% url items:itemform %}?i={{item.id}} 发出的初始GET 请求以return render(...) 响应,以在加载了正确模型实例的模式内呈现模板。理想情况下,我希望能够在遇到表单错误时重新呈现相同的模板,因为它使用的模板已准备好处理显示这些错误。
    • 如果您返回的模板比您需要提供的整个表单位于必须保持完整的 div 内 - 因为整个模态窗口将被重新加载。
    • 我在原始问题中添加了一些信息;视图在遇到无效提交时会返回完整的表单和模板。我明白你所说的保持在同一个 div 内(无论如何都是这个概念),我只是认为当前视图会实现这一点,因为它为 GET 请求和响应无效表单数据执行相同的 render 块.
    • 所以你可以做的是让所有场景都返回渲染,但添加错误作为字典的一部分,而不是 Django 表单验证具有单独的重定向。只需在渲染中向字典中添加更多消息,例如 {'form':form, 'instance':instance,'error1':error1} 然后使用 {{ error1 }}
    猜你喜欢
    • 2021-03-25
    • 1970-01-01
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 2019-07-12
    • 1970-01-01
    相关资源
    最近更新 更多