使用Django Forms+Google Places Autocomplete时AJAX传参异常问题
Django Forms对接Google Places Autocomplete序列化异常问题
问题描述
页面重构改用Django Forms(原页面未使用Django Forms),对接Google Places Autocomplete获取数据,流程为接收谷歌接口响应转换为JSON后,结合表单数据发起AJAX请求。
当前异常:通过AJAX序列化表单传参时,存储JSON值的google-details字段被包裹为数组格式;原页面无此问题,谷歌接口返回数据格式正常。
处理谷歌数据的JavaScript逻辑与原页面一致,均通过.val(JSON.stringify())将数据更新到HTML的google-details字段中。
相关代码
<form id="myForm"> <input type="hidden" id="google-details" name="google-details"> {{ form }} <button type="submit" id="submit">submit </form> <script type="text/javascript"> $(document).ready(function () { $("#myForm").on("submit", function () { event.preventDefault(); do_ajax_call(); } } function do_ajax_call() { let foo = $("#myForm").serialize(); $.ajax({ url: '/destination/', type: 'post', data: foo, success: function(res) { //Do stuff } }) } </script>
异常数据(AJAX收到的格式)
['{"address_components":[{"long_name":"20","short_name":"20","types":["street_number"]},{"long_name":"West 34th Street","short_name":"W 34th St.","types":["route"]},{"long_name":"Manhattan","short_name":"Manhattan","types":["sublocality_level_1","sublocality","political"]},{"long_name":"New York","short_name":"New York","types":["locality","political"]},{"long_name":"New York County","short_name":"New York County","types":["administrative_area_level_2","political"]},{"long_name":"New York","short_name":"NY","types":["administrative_area_level_1","political"]},{"long_name":"United States","short_name":"US","types":["country","political"]},{"long_name":"10001","short_name":"10001","types":["postal_code"]}],"business_status":"OPERATIONAL","formatted_address":"20 W 34th St., New York, NY 10001, USA","name":"Empire State Building","place_id":"ChIJaXQRs6lZwokRY6EFpJnhNNE","types":["tourist_attraction","museum","point_of_interest","establishment"],"url":"https://maps.google.com/?cid=15074921902713971043","html_attributions":[]}', '', '', '']
期望数据(原页面正常格式)
{"address_components":[{"long_name":"20","short_name":"20","types":["street_number"]},{"long_name":"West 34th Street","short_name":"W 34th St.","types":["route"]},{"long_name":"Manhattan","short_name":"Manhattan","types":["sublocality_level_1","sublocality","political"]},{"long_name":"New York","short_name":"New York","types":["locality","political"]},{"long_name":"New York County","short_name":"New York County","types":["administrative_area_level_2","political"]},{"long_name":"New York","short_name":"NY","types":["administrative_area_level_1","political"]},{"long_name":"United States","short_name":"US","types":["country","political"]},{"long_name":"10001","short_name":"10001","types":["postal_code"]}],"business_status":"OPERATIONAL","formatted_address":"20 W 34th St., New York, NY 10001, USA","name":"Empire State Building","place_id":"ChIJaXQRs6lZwokRY6EFpJnhNNE","types":["tourist_attraction","museum","point_of_interest","establishment"],"url":"https://maps.google.com/?cid=15074921902713971043","html_attributions":[]}
解决方案
核心原因
页面中存在多个同名的google-details字段:手动添加的隐藏字段,与Django Form渲染出的同名字段重复。表单序列化时会收集所有同名字段的值,最终打包成数组返回。
具体修复方法
方法1:统一使用Django Form定义字段
移除模板中手动添加的<input type="hidden" id="google-details" name="google-details">,直接在Django Form类中定义该字段:
from django import forms class DestinationForm(forms.Form): # 其他业务字段... google_details = forms.CharField(widget=forms.HiddenInput(), required=False)
模板简化为:
<form id="myForm"> {{ form }} <button type="submit" id="submit">submit</button> </form>
方法2:过滤序列化后的重复字段
如果无法修改Form结构,可在JS中过滤掉空值的google-details字段:
function do_ajax_call() { // 将表单数据转为数组格式 let formDataArray = $("#myForm").serializeArray(); // 过滤掉空的google-details字段,只保留有值的条目 let cleanedData = formDataArray.filter(item => { return !(item.name === "google-details" && item.value.trim() === ""); }); // 重新序列化为请求参数 let foo = $.param(cleanedData); $.ajax({ url: '/destination/', type: 'post', data: foo, success: function(res) { // 后续逻辑 } }) }
方法3:检查页面字段唯一性
打开浏览器开发者工具(F12)查看页面HTML,确认google-details字段是否重复出现。若存在多个同名字段,删除多余的,仅保留一个用于存储谷歌返回的JSON数据。
内容的提问来源于stack exchange,提问作者Ethan
相关产品推荐
相关产品推荐

