Django url重写并从Javascript传递参数

Django url rewrites and passing a parameter from Javascript

本文关键字:参数 Javascript url 重写 Django      更新时间:2023-09-26

作为我前面的一个后续问题,我需要向视图传递一个参数。在JS执行之前,这个参数是不知道的。

在我的URLConf:

url(r'^person/device/program/oneday/(?P<meter_id>'d+)/(?P<day_of_the_week>'w+)/$',
therm_control.Get_One_Day_Of_Current_Thermostat_Schedule.as_view(), 
name="one-day-url"),

我可以传递这个URL,它工作得很好!(感谢你们)。

http://127.0.0.1:8000/personview/person/device/program/oneday/149778/Monday/

在我的模板中:

var one_day_url = "{% url personview:one-day-url meter_id=meter_id day_of_the_week='Monday' %}";

在我的javascript中:

 $.ajax({
        type: 'GET',
        url: one_day_url ,
        dataType: "json",
        timeout: 30000,
        beforeSend: beforeSendCallback,
        success: successCallback,
        error: errorCallback,
        complete: completeCallback
    });

当这个触发时,它工作得很好,除了我不一定总是想要星期一。

如果我把javascript改成这样:

var one_day_url = "{% url personview:one-day-url meter_id=meter_id %}";
and then
$.ajax({
        type: 'GET',
        url: one_day_url + '/Monday/',
        dataType: "json",
        timeout: 30000,
        beforeSend: beforeSendCallback,
        success: successCallback,
        error: errorCallback,
        complete: completeCallback
    });

我得到捕获NoReverseMatch而渲染错误。我猜想是因为URLconf仍然希望重写以包含?P'w+)。

我似乎如果我改变URL配置,打破了找到视图的能力,如果我做我上面所做的,它给我NoREverseMatch错误。

请指教。

我通常按照

var one_day_url = "{% url personview:one-day-url meter_id=meter_id day_of_the_week='REPLACE_ME' %}";
// ...
url: one_day_url.replace('REPLACE_ME', 'Sunday')

你可能想用这种项目来回答这个精确的问题…

注意:这可能会帮助黑客映射网站:https://github.com/Dimitri-Gnidash/django-js-utils

当我不使用这个项目时,我会在url中设置一个默认值,并将其替换为正确的值。

因此使用完全相反的then:

url: one_day_url.replace('/Monday/','/Caturday/')

即使你把星期一换成星期一也可以…

注意:如果你的默认值已经在url中,那么这个丑陋的hack将会失败,因此使用它

为什么不直接将它们作为请求数据的一部分传入呢?您可以使用jQuery的get函数并将它们作为参数传递。

$.get("{%url personview%}", {'meter_id':"meter_id", "day_of_the_week":"monday" ...}, function(){do stuff when info is returned});

在你的视图中,你可以这样做:

meter = request.GET['meter_id']

这将允许您在视图中使用它

我也有类似的问题。我想在有人点击按钮时打开一个URL。下面是我处理这种情况的方法。

将URL定义为一个属性:

{% for article in articles %}    
  <button data-article-url="{% url view_article article.id %}">
    Read Article #{{ article.id }}
  </button>
{% endfor %}

使用jQuery读取属性并继续:

var article_url = $(this).attr("data-article-url");
$.ajax({
  url: article_url,
  ...
});

您可以在url中使用令牌,并将其作为变量传递给模块:

<script src="{{ STATIC_URL }}js/my-module.js"></script>
<script>
$(function(){
    MyModule.init(
        "{% url personview:one-day-url meter_id='0000' day_of_the_week='{day}' %}"
    );
});
</script>
// js/my-module.js
var MyModule = {
    init: function(one_day_url) {
        var id = 1, day = 'Saturday';
        this._one_day_url = one_day_url;
        console.log(this.one_day_url(id, day));
        $.ajax({
            type: 'GET',
            url: this.one_day_url(id, day),
            dataType: "json",
            timeout: 30000,
            beforeSend: beforeSendCallback,
            success: successCallback,
            error: errorCallback,
            complete: completeCallback
        });
    },
    one_day_url: function(meter_id, day) {
        return this._one_day_url.replace('0000', meter_id).replace('{day}', day);
    }
};

注意,token应该匹配regex类型才能成功解析(我不能使用{meter_id},因为它是用'd+定义的)。

我对这个解决方案有点不满意,最后我用django: django.js写了我自己的应用程序来处理javascript。在这个应用程序中,我可以做:

{% load js %}
{% django_js %}
{% js "js/my-module.js" %}
// js/my-module.js
var MyModule = {
    init: function() {
        var id = 1, day = 'Saturday';
        console.log(
            Django.url('personview:one-day-url', id, day),
            Django.url('personview:one-day-url', [id, day]),
            Django.url('personview:one-day-url', {
                meter_id: id,
                day_of_week: day
            })
        );
        $.ajax({
            type: 'GET',
            url: Django.url('personview:one-day-url', id, day),
            dataType: "json",
            timeout: 30000,
            beforeSend: beforeSendCallback,
            success: successCallback,
            error: errorCallback,
            complete: completeCallback
        });
    }
};
$(function(){
    MyModule.init();
});