9

有很多帖子和页面讨论了 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 的片段(不起作用):

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。)

在此先感谢您的帮助。

4

4 回答 4

17

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

由于您正在进行 ajax 调用,并且 ajax 调用依赖于一些用户输入,通常客户端向服务器发送任何类型的用户输入的最佳途径是使用查询字符串(?URL 中的内容)或发送一个POST数据。因此,最简单的方法是更改​​您的 url,使其不包含在 url 中,而是让视图将其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,
    ...
});
于 2012-11-12T04:43:35.627 回答
3

可以使用属性在您选择的元素上设置 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 JAVASCRIPT 上设置的 data-url 属性

$(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 VIEWS 我正在使用 django rest 框架类视图,但您可以使用基于函数或类的视图类 ChartData(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 URLS:从视图中导入视图类

path('api/chart/data', views.ChartData.as_view(), name="chart-data"),
于 2020-05-08T18:09:52.307 回答
0

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

path('myurl/<str:type>', 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>
于 2021-08-25T04:46:37.563 回答
0

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

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

于 2021-04-21T23:30:24.653 回答