【问题标题】:Django and Ajax trouble with POST addressPOST 地址的 Django 和 Ajax 问题
【发布时间】:2016-07-12 06:03:00
【问题描述】:

我偶然发现了 Django 和 JQuery/Ajax 的一个非常特殊的问题 网址中有地址:

url(r'^app/insert$', Insert.as_view(), name="insert"),
url(r'^app/insert_ajax$', Insert_Ajax.as_view(), name="insert_ajax"),
url(r'^app/edit/(?P<id>\d+)/$', Edit.as_view(), name="edit"),

如您所见,它们都是基于对象的视图。还有一个模型:

class TheModel(models.Model):
    item = models.ForeignKey(AnotherModel, related_name="anotherModel")
    attribute = models.ForeignKey(ListOfAttributes, related_name="attributes", blank=True)

以及基于给定模型的表格:

class TheModelForm(forms.ModelForm):
    class Meta:
        model = TheModel

所以交易是属性必须根据给定项目更改(过滤)。有一个 JQuery 可以处理:

    var change_attribute = function(){

    var selected_item_id = $("#selected_item_id").val();
    $.post("insert_ajax",{"method":"get_attributes","item":$("#id_item").val()}, function( data ) {
        $("#id_attributes").empty();
        $.each(data,function(index, value){
            if(value['id'] == selected_item_id){
                $("#id_attributes").append("<option selected='selected' value='"+ value['id'] +"'>"+value['name']+"</option>");
            }else{
                $("#id_attributes").append("<option value='"+ value['id'] +"'>"+value['name']+"</option>");
            }
        });
    });

}

这直接进入 Ajax 视图:

class CallDropAjax(View):

    def post(self, request):
        method = request.POST.get('method', None)
        context = {}
        if method:
            try:
                context = getattr(self, method)(request)
            except AttributeError as e:
                context = json.dumps({'success': False,
                                      'error': 'Method %s cannot be called due to %s.' % (method,
                                                                                          str(e))})
        else:
            context = json.dumps({'success': False,
                                  'error': 'No method specified'})

        return HttpResponse(context, content_type="json/application")

    def get_attributes(self, request):
        attributes = ListOfAttributes.objects.filter(
            item__id=request.POST.get('item'))
        json_op = []
        for attribute in attributes:
            json_op.append({"id": attribute.id,
                            "name": attribute.name})
        return json.dumps(json_op)

插入和编辑视图/表单都使用相同的 JQuery 脚本,但它仅适用于插入,而不适用于编辑。当我查看数据时,插入正确地要求服务器

http://the_server/app/insert_ajax

所以服务器响应,属性的下拉列表被过滤和相应的修改。但是在版本视图中它不起作用,当我查看 ajax 向服务器请求什么时,结果是这样的:

http://the_server/app/edit/2453/insert_ajax

这当然是错误的,因此脚本不会接收任何数据,也不会修改任何内容(它只是将所有数据留在下拉列表中)。

所以我的问题是:为什么会发生这种情况,我该如何解决?如何使此脚本在版本视图和插入视图中都有效?

【问题讨论】:

    标签: jquery ajax django post filter


    【解决方案1】:

    我假设/app/edit/2453/ 是一个可见的网址。

    当您从 /app/edit/2453/ 编辑内容时,JQuery 会向 url + insert_ajax 触发 AJAX POST 请求。

    看到这一行:

    $.post("insert_ajax",{"method":"get_attributes","item......
    

    您可以通过将“insert_ajax”替换为编辑页面的完整相对 url (/app/edit/2453/) 来修复此行为。

    【讨论】:

    • 我是这么想的,但是在那种情况下,ajax在插入时的完整地址应该是/app/insert/insert_ajax,但事实并非如此——它是/app/insert_ajax,所以我很困惑为什么它会在版本末尾附加 insert_ajax。我有没有提到,所有视图都在同一个文件中?它有什么改变吗?此外,我试图只提供一个完整的应用程序 URL 而不是 django 名称,但它只是将整个地址附加到版本 URL...
    • 发生这种情况是因为与编辑 url 不同,其他 url DO NOT/ 结尾。当 url 不以正斜杠结尾时,当前页面(url 的最后一部分)将替换为 insert_ajax。避免混合正斜杠网址结尾。
    • 我想这是有道理的。但是有一个问题,这个数字实际上是数据库中一个项目的 ID 号。现在我正在考虑如何解决这个问题,因为第一次启动是使用 get 方法,所以数据必须以某种方式发送/处理/显示。
    【解决方案2】:

    我解决了!

    我不得不更改 urls.py 并添加另一行:

    url(r'^app/insert$', Insert.as_view(), name="insert"),
    url(r'^app/insert_ajax$', Insert_Ajax.as_view(), name="insert_ajax"),
    url(r'^app/edit/(?P<id>\d+)$', Edit.as_view(), name="edit"),
    url(r'^app/edit/insert_ajax$', Insert_Ajax.as_view(), name="insert_insert_ajax"),
    

    所以现在可以在编辑中调用该脚本,它会发现它回到了同一个视图处理程序 Insert_Ajax。

    我还必须修改 JQuery 脚本,以便它运行两个调用 - 对 insert_ajax 和 insert_insert_ajax:

    var post_change = function(){
    
        var selected_id = $("#selected_id").val();
        $.post("insert_ajax",{"method":"get_attributes","item":$("#id_item").val()}, change_item);
        $.post("insert_edit_ajax",{"method":"get_attributes","item":$("#id_item").val()}, change_item);
    }
    

    并将响应处理程序扔给不同的函数“change_item”(这样我就不必复制+粘贴代码了。

    而且它有效!这不是一个非常优雅的解决方案,对两个视图的冗余调用希望它们中的一个响应,但现在它会做。也许我会在以后学习如何检查 URL 调用是否成功时更改它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-05
      • 1970-01-01
      • 2013-02-25
      • 2010-12-05
      • 2021-11-01
      • 2011-11-01
      • 1970-01-01
      • 2018-09-02
      相关资源
      最近更新 更多