Django Crispy Form将JSON呈现为HTML

时间:2015-12-27 16:04:47

标签: python json ajax django django-forms

当我的脆皮表单第二次提交时,它会显示JSON而不是重定向到成功页面或显示错误。第一次像魅力一样。

第二次提交时未触发Validator.js 。因此,Ajax不处理JSON,这就是它显示为HTML的原因。

我已尝试event.preventDefault();,从提交按钮中删除type="submit",从表单中删除actionmethod并从隐藏的输入中抓取它。

GitHub repo

呈现为HTML的JSON

{"success": false, "form_html": "\n\n<form  class=\"form-crispy\" ... }

enter image description here

HTML表单

<form  class="form-crispy" id="form-grab" next="/transactions/" action="/transactions/add/" method="post" >
    <input type='hidden' name='csrfmiddlewaretoken' value='AfUGrMclChV1ctI6F5iw93EYyKpuB5Oh' />
    FIELDS
    ....
    <button  type="submit" class="btn button-submit" id="form-submit">Submit</button>
    <a href="/transactions/" class="button-cancel" role="button">Cancel</a>
</form>

<script src="/static/budget/js/validator.js"></script>

Validator.js

$("#form-submit").click(function(event) {
    event.preventDefault();
    alert('Fired');

    var form = $('#form-grab');

    $.ajax({
        url: form.attr('action'),
        type: form.attr('method'),
        data: form.serialize(),
        success: function (data) {
            if (!(data['success'])) {
                form.replaceWith(data['form_html']);
            }
            else {
                var next = form.attr('next');
                window.location.replace(next);
            }
        },
        error: function () {
            form.find('.error-message').show()
        }
    });
});

Views.py

@login_required(login_url='/login/', redirect_field_name='next')
@json_view
def add_transaction(request):
    user = get_user_in_session(request.session)
    data = {'user': user}

    if request.method == 'POST':
        form = TransactionAddForm(request.POST, initial=data)
        if form.is_valid():
            budget = form.cleaned_data['budget']
            description = form.cleaned_data['description']
            amount = form.cleaned_data['amount']
            transaction_date = form.cleaned_data['transaction_date']
            creation_date = now().date()
            transaction = Transaction(
                    budget=budget,
                    description=description,
                    amount=amount,
                    transaction_date=transaction_date,
                    creation_date=creation_date
            )
            transaction.save()
            return {
                'success': True,
            }
        context = {}
        context.update(csrf(request))
        form_html = render_crispy_form(form, context=context)
        return {
            'success': False,
            'form_html': form_html,
        }
    else:
        form = TransactionAddForm(initial=data)
        return render(request, 'base_form.html', {
            'title': 'Add Transaction',
            'form': form,
        })

1 个答案:

答案 0 :(得分:0)

啊哈,

我认为问题在于replaceWith jquery方法,它不仅删除了数据,还删除了链接到html的已移除节点的事件处理程序。

可能的解决方案是在replaceWith之后重新挂起事件。在上面的代码中:

...
form.replaceWith(data['form_html']);
# reattach
$("#form-submit").on('click', function(event){
  event.preventDefault();
  # continue with invoking ajax post function
});