【问题标题】:How to return django form object in an AJAX request from django template?如何在来自 django 模板的 AJAX 请求中返回 django 表单对象?
【发布时间】:2015-10-14 03:34:25
【问题描述】:

我正在尝试通过 Ajax 调用从 django 模板调用我的视图。

我希望表单对象响应视图,以便我可以通过 jquery 在 div 元素中呈现此表单。

有可能吗?怎么样?

这是我尝试过的:

home.html

function get_edit_form(button, id)
  {
        $.ajax({
            url: "/manage/licenses/{{mls_signup_code}}/{{agent_id}}/" + id + "/",
            type: "get",
            data: {id: id},
            success: function(response) {
            console.log(response);
            $("#formdiv").html({{ response.as_p }});
            }
        })
  }

Views.py

elif request.method == "GET":
        owned_license_id = request.GET.get('id', '')
        form = OwnedLicenseForm(owned_license_id)
        return form

【问题讨论】:

  • 你试过了吗?
  • @Gocht:请检查,编辑
  • 我猜这会引发一个序列化错误,你应该返回一个 json。为什么需要将表单作为对象传递?
  • 不,它没有,它什么都不做,只是在控制台对象中显示此错误没有属性'status_code,我明白为什么。我尝试使用 return HttpResponse(form) ,但我没有看到任何表单标签,它只呈现表单值
  • 你需要HttpResponse,See

标签: python django django-templates


【解决方案1】:

我明白你在做什么,但你不能以这种方式呈现 html 表单:

$("#formdiv").html({{ response.as_p }});

我认为您将服务器端渲染(Django 模板)与客户端渲染混淆了。服务器端渲染发生在您的服务器处理请求时,它无法渲染浏览器中运行的 javascript 生成的对象。

因为response是一个javascript对象,通过jquery向你的url发送Ajax请求获得。此时页面已经被 Django 的模板引擎渲染,并发送到浏览器。 Django 模板甚至无法意识到这个response

我知道你想使用 as_p() 方法来渲染表单,你可以这样做:

function get_edit_form(button, id)
{
        $.ajax({
            url: "/manage/licenses/{{mls_signup_code}}/{{agent_id}}/" + id + "/",
            type: "get",
            data: {id: id},
            success: function(response) {
              console.log(response);
              // response is form in html format
              $("#formdiv").html(response);
            }
        })
  }

# Views.py
elif request.method == "GET":
        owned_license_id = request.GET.get('id', '')
        form = OwnedLicenseForm(owned_license_id)
        return HttpResponse(form.as_p()) # return a html str

【讨论】:

    【解决方案2】:

    您可以结合使用 Django 和 JQuery 来完成此操作。

    第 1 步:创建一个超简单的 form_from_ajax.html 模板

    模板可以简单到{{form.as_p}}。关键是继承您的基本模板。您只是使用这个 form_from_ajax.html 模板来呈现表单的 HTML。

    第 2 步:使用 slug 参数创建一个视图,帮助您获得正确的表单

    def payment_method_ajax(request, method):  # method is your slug
        """Load a dynamic form based on the desired payment method"""
    
        options = {
            'ach': ECheckForm(),  # Dynamic form #1
            'credit-card': CreditCardForm(),  #  Dynamic form #2
        }
    
        if method in options.keys():
            context = {'form': options[method]}
        else:
            context = None
    
        template = 'your_app_name/form_from_ajax.html'
        return render(request, template, context)
    

    第三步:在 urls.py 中定义 AJAX url

    [...
        path(
            'payment-method-ajax/<slug:method>/',  # notice the slug in the URL
            views.payment_method_ajax,
            name='payment-method-ajax'),
    ...]
    

    第 4 步:更新您希望显示 AJAX 加载表单的模板

    制作一些按钮让用户选择适当的表单选项

    <button id="btn_ach" onclick="load_payment_form(this)">ACH</button>
    <button id="btn_credit_card" onclick="load_payment_form(this)">Credit Card</button>
    

    form-fields 是加载动态表单的地方

    <form id="id-form" style="display: none;">
        {% csrf_token %}
    
        <div id="form-fields"></div>
        <input type="submit" value="Save Payment Details"/>
    </form>
    

    确保将 slug 添加到主视图的上下文中

    context = {
            'target': 'Add a New Payment Method',
            'h1': 'Add a New Payment Method',
            'ach': 'Save an ACH Profile',
            'credit_card': 'Save a Credit Card Profile',
            'slugs': ['ach', 'credit-card'],  # Here are the slugs ****
        }
    

    第 5 步:使用 JQuery 和按钮的 onclick 加载表单

    <script>
        var ach = 'ACH';
        var creditCard = 'Credit Card';
    
        var form_urls ={
            ach : '{% url "payment-method-ajax" slugs.0 %}',
            creditCard : '{% url "payment-method-ajax" slugs.1 %}',
        }
    
        function load_payment_form(btn) {
    
            if(btn.innerText==ach) {
                get_url = form_urls['ach'];
                type = ach;
            }
            else if(btn.innerText==creditCard) {
                console.log('Load credit card form');
                get_url = form_urls['creditCard'];
                type = creditCard;
            }
    
            $.get({'url': get_url}).done(
    
                   function(data) {
                    document.getElementById('form-fields').innerHTML = data;})
    
            document.getElementById("id-form").style.display = "block";
        }
    </script>
            
    

    【讨论】:

      猜你喜欢
      • 2012-02-11
      • 2011-02-07
      • 2012-01-08
      • 2012-01-13
      • 1970-01-01
      • 2011-11-29
      • 2015-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多