从HTML页面的JavaScript函数调用Python方法获取数据
使用的技术
- 谷歌应用引擎
- Django
- Python
- Jquery
代码细节和代码片段
我有一个下拉列表(国家)和一个文本框(城市),这两个元素是通过Django表单生成的,能够自动填充,使用的是一个GeoIp库。
下面是这些界面元素在网页上的样子:
填充下拉列表和文本框的代码片段:
// 选择用户的国家和城市, // 用户国家下拉列表的ID是 "id_country_name" // 用户城市文本框的ID是 "id_city_name" $(function () { $("#id_country_name").val(geoip_country_name()); $("#id_city_name").val(geoip_city()); // 到这里,用户的国家和城市值已经通过JavaScript调用获取 // 现在是时候调用Python代码,获取其他用户报告的该国家和城市的数据了}); </script>
查询数据库的示例Python代码
def get_data_for_users_country_and_city(self): query = db.GqlQuery("SELECT * FROM UserReportedCity where county.country_name = country_name and city.city_name = city") data = query.fetch(10)
我可能需要把这些内容打包成一个模板,然后再返回到HTML页面
template_values = {
self.__TEMPLATE_DATA_FOR_USER: data
}
#rendering the html page and passing the template_values
self.response.out.write(template.render(self.__MAIN_HTML_PAGE, template_values))
请注意,我还没有测试这段Python代码。
问题
一旦国家和城市的值通过JavaScript调用填充完毕,我想调用一个Python方法,获取用户国家和城市的数据,并将其填充到“您的城市”标签中。
[编辑#1]
我尝试了@Fabio Diniz和@Kevin P给出的建议。
以下是HTML和JavaScript代码:
<!-- script snippet to fill in users country and city value by making a calls to the geoip library -->
<script type="text/javascript">
// selecting users country and users city,
// the id for users country drop-down list is "id_country_name"
// the id for users city text-box is id_city_name
$(function () {
$("#id_country_name").val(geoip_country_name());
$("#id_city_name").val(geoip_city())
});
$.post("/AjaxRequest/get_data_for_users_country_city", {
selected_country_name: document.getElementById('id_country_name').value,
selected_city_name: document.getElementById('id_city_name').value
},
function(data) {
alert("hello");
}
);
</script>
以下内容表明对“/AjaxRequest/get_data_for_users_country_city”的请求应该发送到“AjaxRequest”类。
def main():
application = webapp.WSGIApplication([('/', MainPage),
('/UserReporting', UserReporting),
('/AjaxRequest/get_data_for_users_country_city', AjaxRequest )
],
debug=False)
run_wsgi_app(application)
在“AjaxRequest”类中的代码
from google.appengine.ext import db
class AjaxRequest(webapp.RequestHandler):
def post(self):
user_reported_country_get = self.request.get('selected_country_name')
user_reported_city_get = self.request.get('selected_city_name')
data_for_users_country_city = self.get_data_for_users_country_and_city(user_reported_country_get, user_reported_city_get)
self.response.out.write (data_for_users_country_city)
问题:
在调试模式下,我可以看到JavaScript方法的调用成功到达了“AjaxRequest”的“post”方法。但问题是“user_reported_country_get”和“user_reported_city_get”没有接收到JavaScript代码传来的字符串值。
[编辑#2]
根据@Matt Ball的建议,我在JavaScript调用中尝试了以下代码片段
<!-- script snippet to fill in users country and city value by making a calls to the geoip library -->
<script type="text/javascript">
// selecting users country and users city,
// the id for users country drop-down list is "id_country_name"
// the id for users city text-box is id_city_name
$(function () {
$("#id_country_name").val(geoip_country_name());
$("#id_city_name").val(geoip_city())
});
$.post("/AjaxRequest/get_data_for_users_country_city", {
selected_country_name: $('#id_country_name').val(),
selected_city_name: $('#id_city_name').val()
},
function(data) {
alert("hello");
}
);
</script>
国家下拉列表和城市文本框的HTML代码片段。这里国家下拉列表的ID是 "id_country_name",城市文本框的ID是 "id_city_name"
<div id="userDataForm">
<form method="POST" action="/UserReporting">
<table>
<!-- Printing the forms for users country, city -->
<tr><th><label for="id_country_name">Country name:</label></th><td><select name="country_name" id="id_country_name">
<option value="" selected="selected">---------</option>
<option value="Afghanistan">Afghanistan</option>
</select></td></tr>
<tr><th><label for="id_city_name">City name:</label></th><td><input type="text" name="city_name" id="id_city_name" /></td></tr>
</table>
</form>
在Python调试器中,“select_country_name”和“selected_city_name”的值仍然是空的,如下图所示
[编辑#3]
我认为在调用Python时,可能发生在“id_country_name”和“id_city_name”值填充之前。因此,我直接传递了geoip_country_name()和geoip_city()的值,而不是尝试传递“id_country_name”和“id_city_name”的值。这样成功地将国家名和城市名传回了Python代码。
这是我尝试的代码片段。
<!-- script snippet to fill in users country and city value by making a calls to the geoip library -->
<script type="text/javascript">
// selecting users country and users city,
// the id for users country drop-down list is "id_country_name"
// the id for users city text-box is id_city_name
$(function () {
$("#id_country_name").val(geoip_country_name());
$("#id_city_name").val(geoip_city())
});
$.post("/AjaxRequest", {
selected_country_name: geoip_country_name(),
selected_city_name: geoip_city()
},
function(data) {
alert($('#id_country_name').val());
alert($('#id_city_name').val())
}
);
</script>
[编辑#4]
根据@hyperslug的反馈,我把“$.post("/AjaxRequest" ”这一部分移动到了设置用户国家下拉列表和城市文本框的函数内部。
这段代码正确地将用户的国家和城市传递给了Python代码。
JavaScript代码片段:
<!-- script snippet to fill in users country and city value by making a calls to the geoip library -->
<script type="text/javascript">
// selecting users country and users city,
// the id for users country drop-down list is "id_country_name"
// the id for users city text-box is id_city_name
$(function () {
//finding the users country and city based on their IP.
var $users_country = geoip_country_name()
var $users_city = geoip_city()
// setting the drop-down list of country and text-box of the city to users country and city resp
$("#id_country_name").val($users_country);
$("#id_city_name").val($users_city);
//since we have users country and city, calling python class to get the data regarding users country and city combination
$.post("/AjaxRequest", {
selected_country_name: $users_country,
selected_city_name: $users_city
})
});
</script>
2 个回答
创建一个页面,用来处理国家和城市的数据请求。然后,使用Ajax把国家和城市的字段发送到这个页面。让这个处理程序根据表单中的字段输出你想要的数据。接着,使用JavaScript把返回的数据插入到你的标签中。
下面是一个请求处理程序的示例:
class GeoData(webapp.RequestHandler):
def post(self):
country = self.request.get('selected_country')
city = self.request.get('selected_city')
data = retrieve_my_data(country,city)
self.response.out.write(data)
你需要使用ajax。jQuery为你提供了一套很不错的接口来实现这个功能。
关于楼主的编辑 - 不妨试试这段代码:
$.post("/AjaxRequest/get_data_for_users_country_city", {
selected_country_name: $('#id_country_name').val(),
selected_city_name: $('#id_city_name').val()
}, function(data) {
alert("hello");
});