我在DOM中有两个选项列表,当视图中的方法加载页面时,首先在加载URL时填充。第二个选项列表的内容取决于用户在第一个选项列表中选择的内容。当用户在第一个选项列表中进行选择时,如何将python方法绑定到事件,在python中进行一些操作,返回我想在第二个选项列表中显示的vallues列表,然后填充它而不刷新页面?
我的模板看起来像这样:
{% block content %}
{% if list_of_events %}
<form>
<select>
{% for event in list_of_events %}
<option value="name">{{ event.module }}</option>
{% endfor %}
</select>
</form>
{% else %}
<p>No events available now.</p>
{% endif %}
下一个条件是等待first_selection参数,该参数应在用户选择第一个选项列表中的值后返回到模板。
{% if first_selection %}
<form>
<select>
{% for room in list_of_rooms %}
<option value="name">{{ room.id }}</option>
{% endfor %}
</select>
</form>
{% endif %}
<input type="submit" value="Submit">
{% endblock %}
我的views.py
方法看起来像这样:
def events(request):
try:
list_of_events = Event.objects.all()
except:
raise Http404('Something\'s wrong with events page loader')
return render(request, 'web_service/schedule.html', {
'list_of_events': list_of_events
})
在Django中(至少现在)没有直接的方法来直接从模板(html)动态调用python方法而不刷新页面。
要调用python方法并在模板中看到它的效果而不刷新页面需要一些JS
。它不像在OOP中调用实例方法那么简单,但并不像看起来那么难。
下面的示例演示如何响应按钮click
并将一些数据发送到django view
,然后将结果返回到模板而不刷新DOM
。
从模板调用python代码的唯一方法与我们与url
相关的方式相关,这意味着我们必须创建新的url pattern
。然后调用必要的view
并将响应返回到模板JsonResponse
。
注意:确保在jquery
标签的内部底部导入<body>
。
首先,我们需要创建响应器,它将处理按钮单击并创建AJAX
请求到连接到view
的URL。 AJAX request
将input
作为参数传递给我们的url模式,这意味着此参数将传递给django view
。如果我们调用view
返回某些内容,那么数据将在success
闭包中解压缩。
假设我们的模板如下所示:
<input type="text" id="user-input" autofocus=""><br>
<button type="button" id="sender">Send data</button><br>
<p id="p-text">foo bar</p>
处理点击和请求的脚本如下所示:
<script>
$("#sender").click(function () {
var input = $('#user-input').val();
$.ajax({
url: '{% url 'get_response' %}',
data: {
'inputValue': input
},
dataType: 'json',
success: function (data) {
document.getElementById('p-text').innerHTML = data["respond"];
}
});
});
</script>
urls.py中需要新模式:
urlpatterns = [
...
url(r'^ajax/get_response/$', views.answer_me, name='get_response')
...
]
注意:url的ajax/
部分和url模式的路径本身对如何处理此调用没有影响。它可以是你想要的任何东西,例如:^foo/bar/$
。
最后一步是添加响应Django view
。这个简单的示例返回带有一些附加文本的输入,但通常这是您可以调用其他python方法并执行任何操作的地方:
def answer_me(request):
field = request.GET.get('inputValue')
answer = 'You typed: ' + field
data = {
'respond': answer
}
return JsonResponse(data)
您可以使用display = none呈现所有可能的第二个选项列表,然后您可以添加如下的javascript:
function show(select_item) {
if (select_item == "apple") {
hiddenDiv.style.visibility='visible';
hiddenDiv.style.display='block';
Form.fileURL.focus();
}
else{
hiddenDiv.style.visibility='hidden';
hiddenDiv.style.display='none';
}
}
</script>
<form>
<label>Fruit:</label>
<select name="Fruit" onchange="java_script_:show(this.options[this.selectedIndex].value)">
<option value='pear'>pear</option>
<option value='apple'>apple</option>
<option value='grapes'>grapes</option>
</select>
<div id='hiddenDiv' style="display: none;">
<label>Are you sure you want to eat the apple?</label>
<select name="AppleQuestion">
<option value='Yes'>Yes</option>
<option value='No'>No</option>
</select>
</div>
</form>