【问题标题】:Using the Django URL Tag in an AJAX Call在 AJAX 调用中使用 Django URL 标签
【发布时间】:2012-10-31 12:33:56
【问题描述】:

有很多帖子和页面讨论了 Django 和 AJAX 的使用,我在过去一天左右阅读了数百篇文章来寻找这个问题的答案。快速概览:

可能的示例显示了这样的硬编码 URL:

$.post("/projects/create/", {"name" : name}, function(data) {...

或者有些使用 URL 模板标签,但没有参数:

$.post("{% url create_project %}", {"name" : name}, function(data) {...

但是,我想在 URL 中包含一个 Django 样式的参数。这是我的网址定义:

url(r'ajax/entity_name/(?P<pk>\w+)/$',EntityAjaxView.as_view(),name='entity_name'),

是的,我使用的是基于类的视图,它基于 DetailView。默认情况下,此视图会查找要在 URL 中提供的 pk 值,并且在我将使用的普通模板中:

{% url entity_name id_number %}

提供链接。在我的代码中,我想获取在输入框中输入的值作为 pk 值。这是我的 JavaScript 的 sn-p(不起作用):

var id_number = $('#id_endowmententity_set-' + rownum + '-id_number').val()
$.ajax({
    type: "GET",
url: '{% url entity_name id_number %}',

那么,我的问题是,我可以将 URL 模板标签与输入框中的值一起使用吗?

(我知道我可以使用 POST 代替 GET 并在 POST 数据中传递 id_number,但这不适用于 DetailView。)

提前感谢您的帮助。

【问题讨论】:

    标签: ajax django


    【解决方案1】:

    Django 是一个服务器端应用程序。 Javascript是客户端。 Django 模板在服务器上呈现,因此在服务器端评估 {% url entity_name id_number %},然后将其值返回给客户端。正因为如此,你不可能将 Django 模板与 javascript 结合起来。但是,您可以采取一些措施来解决您的问题。

    由于您正在进行 ajax 调用,并且 ajax 调用取决于一些用户输入,通常客户端向服务器发送任何类型的用户输入的最佳途径是使用查询字符串(? 之后的内容) URL)或发送POST 数据。因此,最简单的方法是更改​​您的网址,使其不在网址中包含pk,而是让视图将其作为GETPOST 数据的一部分。

    url(r'ajax/entity_name/$', EntityAjaxView.as_view(), name='entity_name'),
    

    和视图(对不起,我不熟悉基于类的视图):

    def entity_name(request):
        pk = request.GET.get('pk')
        ...
    

    在我看来,这似乎是最优雅的解决方案。但是,如果您绝对需要在客户端构建 url,您可以在服务器端生成一个模板 url,然后在客户端替换您需要的任何部分以获得完整的 url。然而,这需要更多的维护,因此更容易出错。这种方法的简单js示例:

    var id_number = $('#id_endowmententity_set-' + rownum + '-id_number').val(),
        url = '{% url entity_name 0 %}'.replace('0', id_number);
    $.ajax({
        type: "GET",
        url: url,
        ...
    });
    

    【讨论】:

    • 我尝试在我的 函数视图 中使用带有命名 URL 的 ajax 回调,例如 err_key="{% url 'pcd_list' %}",并使用它在调用页面上使用 $('#ajxErr').html(var_err + ' &lt;a href=" ' + var_err_url + '"&gt;Check&lt;/a&gt;'); 创建链接 其中 var_err_url 是从 Ajax 调用返回的 err_key 值的变量。 但它失败了。 但是,如果我在我的函数视图中使用err_key="path_generated_from_named_url",它就可以工作。有没有办法像我在上面的第一个示例中尝试那样使用命名的url?
    【解决方案2】:

    可以使用属性在您选择的元素上设置 Ajax url,它的行为类似于 Django url。重要的是,您甚至可以访问 Javascript 文件中的 url。我经常使用它 HTML

    <div class="card-body" id="js-products" data-url="{% url 'chart-data' %}">
        <div class="chart-area">
          <canvas id="testChart"></canvas>
        </div>
      </div>
    

    注意:在父 div 上设置的 data-url 属性 JAVASCRIPT

    $(document).ready(function () {
    
    var endpoint = $("#js-products").attr("data-url");
    var defaultData = [];
    var labels = []
    $.ajax({
        method: 'GET',
        url: endpoint,
        success: function (data) {
            labels = data.labels
            defaultData = data.data_default
            setChart()
    
    
        },
        error: function (error_data) {
            console.log(error_data)
        }
    })
    
    function setChart() {
        var ctx = document.getElementById('testChart').getContext('2d');
        var myChart = new Chart(ctx, {
            type: 'line',
            responsive: true,
            data: {
                labels: labels,
                datasets: [{
                    label: 'Monthly Performance',
                    data: defaultData,
    
                }]
            },
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true
                        }
                    }]
                }
            }
        });
     }
    });
    

    DJANGO 观点 我正在使用 django rest 框架类视图,但您可以使用基于函数或类的视图 类图表数据(APIView):

    authentication_classes = []
    permission_classes = []
    
    def get(self, request, format=None):
        labels = ['Products', 'User', 'May']
        data_default = [SeedProduct.objects.all().count(),
                        User.objects.all().count(), 4]
        data = {
            'labels': labels,
            'data_default': data_default,
        }
    
        return Response(data)
    

    DJANGO 网址: 从视图中导入视图类

    path('api/chart/data', views.ChartData.as_view(), name="chart-data"),
    

    【讨论】:

    • 我认为这是迄今为止许多用例的最佳答案。例如,我有需要用 ajax 调用填充的 。为此,我在需要以这种方式填充的表上使用 data-url。易于在 jquery 中获取和使用。只需确保保护您的端点免受未经身份验证的调用。
    【解决方案3】:

    为了获取 URL 而往返服务器非常耗时。保持 URL 干燥并避免这种情况的最佳策略是生成模拟 Django 的本机 url reverse 函数的 javascript,然后将该代码静态地与客户端 JS 的其余部分一起提供。

    django-render-static 就是这样做的。

    【讨论】:

      【解决方案4】:

      这对我有用。 我的网址是:

      path('myurl/&lt;str:type&gt;', views.myfunction, name='myfunction')

      我的views.py 文件:

      def myfunction(request,type):
          return render(request, "payment.html", context)
      

      在我的模板中,我通过以下方式解决了这个问题:

      <button type="button" class="btn"
          onclick="myfunction('forward');">My Button Name
      </button>
      
      <script>
      function myfunction(type){
          let url = "{% url 'appName:myfunction' 'ok' %}".replace('ok', type);
          $.ajax({
            method: 'POST',
            url: url,
            data: {
                csrfmiddlewaretoken: '{{ csrf_token }}'
            }
        });
        }
      
      </script>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-23
        • 2018-09-16
        • 2014-04-23
        • 2015-07-21
        • 2011-05-09
        • 1970-01-01
        • 1970-01-01
        • 2020-01-16
        相关资源
        最近更新 更多