【问题标题】:Appending extra data to form request将额外数据附加到表单请求
【发布时间】:2016-03-30 16:52:00
【问题描述】:

我正在实现一个 Django 应用程序的功能,在该应用程序中,我有一个表单,该表单可以提交用户的输入并进行 api 调用,该调用返回我解析并显示在页面上的 JSON 响应。查询结果显示在我通过遍历每个对象创建的列表中。在每个列表元素中,我都有一个按钮,单击该按钮会打开一个模式表单。此表单包含电子邮件收件人、全名和用户可以在单击提交和发送电子邮件之前指定的消息的字段。提交表单后,我需要在此表单中附加一些额外数据,以便将其发送到服务器端并添加到电子邮件中。

我看过像this 这样的帖子,似乎在做类似的事情;但是,问题在于 jquery 中的事件处理程序需要知道它需要从哪个列表元素中获取数据,这意味着它必须知道循环的当前迭代才能获取正确的信息。

我应该如何实现这个?

这是根据从服务器端返回的数据制作列表的代码:

var venues = {{venues|safe}};
var dates = {{raw_dts|safe}};
var ticket_statuses = {{ticket_statuses|safe}};
var ticket_urls = {{ticket_urls|safe}};
console.log("length of artist list" + venues.length);
var $list = $("<ul  class='list-group'>");
for(var i = 0; i < venues.length; i++){

    $list.append("<li class='list-group-item'>Artist: {{form_artistSelect}}  Location: " + venues[i].city + ', ' + venues[i].region +' Venue: ' + venues[i].name + 
       "Date: " + dates[i] + "tickets status: " + ticket_statuses[i] + "<br><a href = '" + ticket_urls[i] +"'" + "> ticket link</a>  "+
       "{% if user.is_authenticated %}"+
    "<button id ='invite'type='button' class='btn btn-info btn-lg' data-toggle='modal' data-target='#myModal' venue= " +venues[i] +" date = "+ dates[i] +
    "ticket_url = "+ticket_urls[i]+" artist = {{form_artistSelect}} >Invite a friend</button>  <button id = 'save' type='button' class='btn btn-" + 
    "primary-outline'> Save concert</button> "+
        "{% endif %}"+
            "</li>"); 
}

这是附加数据的 jquery 函数的外壳:

$list.appendTo($("#container"));
$("#mform").submit(function()){
    $('<input />').attr('type','hidden')
        .attr('')
}

编辑:

如果不清楚,我特别需要将用户在模态表单中输入的数据与ticket_urlsvenuesdates 的值捆绑在一起,放在每个数组对应的位置到按钮在列表中的位置。这些数组中的每一个都具有与在服务器端解析 JSON 时相同的数据顺序。对于日期数组,您有这个结构var dates = ["2016-03-18T12:00:00", "2016-03-19T12:00:00", "2016-03-20T12:00:00"],其中第一个日期显示在第一个列表元素中,第二个日期显示在第二个列表元素中,依此类推。例如,如果单击第二个列表元素中的按钮,我需要将表单数据与每个数组第二个位置的每个值一起发送。

我正在考虑以某种方式在原始循环中执行此操作,但我认为这是不可能的。我该怎么做呢?

从views.py查看

 def search(request):
    queryform = SearchForm(request.POST or None)
    modalform = ModalForm(request.POST or None)
    #print "query form is valid = " + str(modalform.is_valid())
    if queryform.is_valid():
        form_artistSelect = urllib2.quote(queryform.cleaned_data.get("artist_select"))
        form_city =   urllib2.quote(queryform.cleaned_data.get("city"))
        form_state = urllib2.quote(queryform.cleaned_data.get("state"))
        mile_radius = urllib2.quote(queryform.cleaned_data.get("radius"))

        #print "testing"
        url = "http://api.bandsintown.com/artists/" + form_artistSelect + "/events/search.json?api_version=2.0&app_id=YOUR_APP_ID&location=" +form_city+","+ form_state+"&radius="+ mile_radius
        data = json.load(urllib2.urlopen(url))

        #url = "http://api.bandsintown.com/events/search?artists[]=" + form_artistSelect + "&location=" +form_city+","+ form_state+"&radius="+ mile_radius + "&format=json&app_id=YOUR_APP_ID"

        context = {
            "queryform" : queryform,
            "modalform" : modalform,
            "data": data
        }
    else:
        context = {
            "queryform" : queryform 

        }

    if modalform.is_valid():
        form_recipient = modalform.cleaned_data.get("rec_email")
        form_message = modalform.cleaned_data.get("message")
        form_recname = modalform.cleaned_data.get("rec_name")
        print form_recipient
        print form_message
        print form_recname
        concert_venue = modalform.cleaned_data.get("additionalValues[venue]")
        concert_date= modalform.cleaned_data.get("additionalValues[uf_date]")
        concert_url = modalform.cleaned_data.get("additionalValues[ticket_url]")
        artist = modalform.cleaned_data.get("additionalValues[artist]")
        print "concert venue"
        print concert_venue
        print "concert date"
        print concert_date
        print "concert_url"
        print concert_url
        print "artist"
        print artist

    return render(request,"searchform.html" , context)

将存储邀请的模型

class Invite(models.Model):
    sender = models.ForeignKey(User, related_name= "invite_sender", on_delete = models.CASCADE)
    #recipient = models.ForeignKey(User, related_name= "invite_recipient", on_delete = models.CASCADE)
    recipient = models.EmailField()
    concert = models.ForeignKey(Concert, on_delete = models.CASCADE)
    artist = models.ForeignKey(Artist, on_delete = models.CASCADE)
    message = models.CharField(max_length = 120, blank = True, null = True)
    date_sent = models.DateTimeField(auto_now_add = True, auto_now = False)

forms.py 中的相关表单

class SearchForm(forms.Form):
    artist_select = forms.CharField()
    city = forms.CharField()
    state = forms.CharField()
    radius = forms.CharField()


class ModalForm(forms.Form):
    rec_email = forms.CharField()
    message = forms.CharField()
    rec_name = forms.CharField()

模板中的 Ajax 调用

$("#mform").submit(function(){
    var c = getCookie('csrftoken');
    //var data1 = $().attr("");
    var extraData = [];
    extraData['venue'] = $("invite").attr("venue");
    extraData['artist'] = $("invite").attr("artist");
    extraData['f_date'] = $("invite").attr("formatted_date");
    extraData['uf_date'] = $("invite").attr("date");
    extraData['ticket_url'] =  $("invite").attr("ticket_url");
    extraData['city'] = $("invite").attr("city");
    extraData['region'] = $("invite").attr("region");
    extraData['artist'] = $("invite").attr("artist");
    $ajax({
        context:this,
        type : 'POST',
        dataType: 'json',
        url: '/artistsearch/',
        data: {
            csrfmiddlewaretoken: c,
            //data_form: data1,
            additionalValues: extraData

        },
        success: function(response){}
    });
});

【问题讨论】:

  • 不清楚你在问什么。当您可以简单地使用 django include 标签或从后端发送模板时,为什么还要附加这样的块 html?
  • 对不起,我的意思是除了点击提交按钮时将发送到服务器的表单字段之外,我还想发送每个数组中的当前元素为@ 987654333@、ticket_statuses[i]ticket_urls[i] 在 for 循环中迭代。另外,从后端发送模板是什么意思?这对我有帮助吗?
  • @DhiaTN 我刚刚更新了帖子,对问题进行了更直接的解释?
  • 使用对 Python 的 Ajax 请求作为每个列表项的 on submit

标签: javascript jquery python django forms


【解决方案1】:

您在上面提供的代码似乎是 Django 和 JQuery 的奇怪组合。

据我所知:

  1. Django 和 JQuery 在不同的阶段工作。 Django先渲染HTML,然后JQuery生效。

  2. 通过 Django 渲染重复的 HTML 代码比通过 JQuery 更有效(我相信您正在尝试这样做)。

您可以在 Django 模板中使用以下内容:

xyz_template.html

{% load staticfiles %}
<html>
    <head>
        <script src="path_to/ajaxpostcsrf.js"></script>
    </head>
    <body>
        <ul  class='list-group'>
            {% for i in range(0,len_venues) %}
               <li class='list-group-item'>
                   Artist: {{form_artistSelect}} 
                   Location: {{venues.i.city}}, {{venues.i.region}} 
                   Venue: {{venues.i.name}} 
                   Date: {{dates.i}} 
                   tickets status: {{ticket_statuses.i}} <br>
                   <a href = {{ticket_urls.i}}> ticket link </a>

                   {% if user.is_authenticated %}
                      <button id ='invite'type='button' class='btn btn-info btn-lg' data-toggle='modal' data-target='#myModal' venue={{venues.i}} date={{dates.i}} ticket_url={{ticket_urls.i}} artist={{form_artistSelect}}> Invite a friend </button>  
                      <button id = 'save' type='button' class='btn btn-primary-outline'> Save concert </button>
                   {% endif %}
               </li> 
            {% endfor %}
        </ul>
    </body>
</html>

通过传递相关的上下文变量来呈现模板(在上面给出的行上),如下所示:

views.py

def abc_view(request):
    template = 'xyz_template.html'
    return render_to_response(template,
                             {'user': <user_object>,
                              'len_venues': len(venues.objects.all()),
                              'form_artistSelect': <artist>,
                              'venues': venues.objects.all(),
                              'dates': <dates_array>,
                              'ticket_statuses': <ticket_status_array>,
                              'ticket_urls': <ticket_urls_array>
                             },
                             context_instance=RequestContext(request))

模板渲染完成后,您可以使用 AJAX(在下面给出的行中)将额外数据与表单提交一起发送:

javascript_file.js

$("#mform").submit(function()){
    var c = getCookie('csrftoken');    
    //Need to add an ajaxpostcsrf.js and call in your html file to use this    
    //--> basically use your way of sending the csrf_token 

    var data1 = $("<pick relevant tag>").attr("<pick relevant data-attr>");
    //save additional data to be added in a variable
    var data2 = $("<pick relevant tag>").attr("<pick relevant data-attr>");
    $.ajax({
        context: this,
        type: 'POST',
        dataType: 'json',
        url: '/your_specific_URL/',
        data: {
              csrfmiddlewaretoken: c,
              data_form: data1,
              data_additional: data2            
        },
        success: function(response) {}
    });
});

ajaxpostcsrf.js

function getCookie(name) {
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
        var cookies = document.cookie.split(';');
        for (var i = 0; i < cookies.length; i++) {
            var cookie = jQuery.trim(cookies[i]);
            // Does this cookie string begin with the name we want?
            if (cookie.substring(0, name.length + 1) == (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

$.ajaxSetup({       
    headers: { "X-CSRFToken": getCookie("csrftoken") }

});

【讨论】:

  • 感谢您的回答,看来可以!我只有几个问题,首先,由于模态表单本身已经处理了自己的数据提交,为什么我需要在 ajax 调用中发送它?由于 Django 清脆表单正在处理数据,因此我似乎无法通过从标签中提取数据来将其发送到此处。此外,网址是否只是视图的名称,在这种情况下是“搜索”?
  • 我现在收到 for 循环的模板语法错误:Could not parse the remainder: '(0,len_values)' from 'range(0,len_values)' 指的是这一行:``` {% for i in range(0,len_values) %}``` 什么可能导致问题?代码是直接复制过来的吗?
  • 请不要照原样复制代码...这里和那里可能会有一些更改..尝试解决错误..因为上面似乎是范围的语法可能是错的......我在这里提供参考:stackoverflow.com/questions/1107737/…
  • 嘿,我让模板循环工作了。现在的问题是来自附加数据的数据没有被发送到服务器,只有输入数据被发送。我尝试将所有额外数据添加到关联数组中,然后将其发送过来,但它不起作用。我已经用新视图和新的 ajax 调用更新了帖子。
  • ajax 请求是否发送到服务器?尝试打开 Google-Developer Tools > Network 并检查您的 AJAX Post 请求是否正在发送到服务器。如果 Ajax Post 没有发送,可能是由于 CSRF 令牌不可用。我在我的答案中添加了一个 JS 代码,您可以将其保存在一个新文件中并调用所有模板以获取 csrf 令牌。看看这是否有效!
【解决方案2】:

如果我正确地理解了你的问题:

  • 如果要显示要添加的元素,除了模型属性之外,您还可以在 ModalForm 类中定义它们。

  • 如果您只需要将数据与表单一起发送而不向用户显示。如果您可以将数据作为视图级别检索,我认为没有必要。我的意思是,在您看来,您的做法如下:

if form.is_valid():
    form_data = form.cleaned_data
    additional_data = # here you get your data, eventually through Queryset
    # ... continue processing your data here
    # 

【讨论】:

  • 感谢您的回答。但是,如果我要执行第二个选项,我将如何跟踪需要发送哪些数据(即,如何发送特定于按下按钮的列表元素 (
  • ) 的数据)?似乎如果我只是尝试获取视图中的所有其他数据,我将无法具体知道要获取的数据索引。我认为第一个解决方案可能会使其工作,尽管我不确定如何将每个数据点附加到模板中的表单字段。
  • 我猜你在提交的数据中有一些东西,这将有助于从数据库中检索想要的数据。您应该分享您的表单视图和模型,否则我无法给您确切的答案。
  • 谢谢,我刚刚在帖子中添加了相关的视图、模型和表单。我试图从这里发送数据的表单称为 ModalForm。另外,我并没有真正尝试从数据库中检索数据。发送请求后,我需要将表单中的数据以及其他数据(正在附加)保存到 models.py 中的邀请表中。
  • 猜你喜欢
    相关资源
    最近更新 更多
    热门标签