Python 将JS变量发布到Django视图,并在单独的模板中显示为上下文变量
我正在努力实现三件事:Python 将JS变量发布到Django视图,并在单独的模板中显示为上下文变量,python,django,Python,Django,我正在努力实现三件事: 在一个模板中使用标准HTML表单收集一些用户输入(下面是questions.HTML) 将该输入发布到myviews.py;最后 将该输入作为上下文变量显示在单独的模板中(results.html如下) 一旦这项工作开始,在将一些输出作为上下文变量传递之前,我将对views.py中的输入进行一些处理,但首先我需要了解从一个模板-->views.py-->中的用户输入移动到另一个模板中的上下文变量的基本原理 另外,我故意这样做而不接触任何数据库,因为我不想保存任何用户数据
questions.HTML
)李>
views.py
;最后results.html
如下)views.py
中的输入进行一些处理,但首先我需要了解从一个模板-->views.py-->中的用户输入移动到另一个模板中的上下文变量的基本原理
另外,我故意这样做而不接触任何数据库,因为我不想保存任何用户数据
以下是我收集年龄和教育水平的问题.html
:
<script type="text/javascript">
$(document).ready(function(){
$('#submit_answers').submit(function (event) {
var user_age = document.getElementById("age-choice").value;
var user_education = document.getElementById("education-choice").value;
$.ajax({
type:"POST",
url:"{% url 'results' %}",
data : {
'age': user_age,
'education': user_education,
'csrfmiddlewaretoken':$("input[name=csrfmiddlewaretoken]").val()
},
})
}
)});
</script>
<p>Please answer the following questions:</p>
<p>What is your age?</p>
<form action="" method="GET" id="age-dropdown">
{% csrf_token %}
<select class="browser-default custom-select" id="age-choice">
<option value="18-30">18-30</option>
<option value="30-40">30-40</option>
<option value="40-50">40-50</option>
<option value="50-65">50-65</option>
<option value="65-100">Over 65</option>
</select>
</form>
<p>What is your highest level of education?</p>
<form action="" method="GET" id="education-dropdown">
{% csrf_token %}
<select class="browser-default custom-select" id="education-choice">
<option value="None">None</option>
<option value="GCSE">GCSE</option>
<option value="A-level">A-level</option>
<option value="University">University</option>
<option value="Postgraduate">Postgraduate</option>
</select>
</form>
<form id="submit_answers" method="post">
{% csrf_token %}
<input type="submit" name="submit_answers" class="btn btn-primary btn-sm pull-right" value="Submit" />
</form>
这是我的视图。py
:
urlpatterns = [
path('', HomePageView.as_view(), name='home'),
path('questions/', QuestionsView.as_view(), name='questions'),
path('results/', ResultsView.as_view(), name='results'),
]
class QuestionsView(TemplateView):
template_name = 'questions.html'
class ResultsView(TemplateView):
template_name = 'results.html'
def answers(request):
if request.method == 'POST':
context = {}
context["age"] = request.POST['age']
context["education"] = request.POST['education']
return context
EDUCATION_CHOICES= [
('none', 'None'),
('gcse', 'GCSE'),
('alevel', 'A-level'),
('university', 'University'),
]
class UserInputForm(forms.Form):
age = forms.IntegerField(label='Enter your age')
education = forms.CharField(label='What is your highest level of education?', widget=forms.Select(choices=EDUCATION_CHOICES))
和results.html
:
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
<form action="/results/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
我做错了什么?感谢@DanielRoseman和@Matthias的建议。我按照Daniel的建议切换到表单,Matthias的建议放弃JS,如下所示: 首先是表单,
forms.py
:
urlpatterns = [
path('', HomePageView.as_view(), name='home'),
path('questions/', QuestionsView.as_view(), name='questions'),
path('results/', ResultsView.as_view(), name='results'),
]
class QuestionsView(TemplateView):
template_name = 'questions.html'
class ResultsView(TemplateView):
template_name = 'results.html'
def answers(request):
if request.method == 'POST':
context = {}
context["age"] = request.POST['age']
context["education"] = request.POST['education']
return context
EDUCATION_CHOICES= [
('none', 'None'),
('gcse', 'GCSE'),
('alevel', 'A-level'),
('university', 'University'),
]
class UserInputForm(forms.Form):
age = forms.IntegerField(label='Enter your age')
education = forms.CharField(label='What is your highest level of education?', widget=forms.Select(choices=EDUCATION_CHOICES))
然后是表单模板,userinputform.html
:
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
<form action="/results/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
最后,results.html
:
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
<form action="/results/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
结果:
年龄:{{Age}}
教育:{{教育}
感谢@DanielRoseman和@Matthias的建议。我按照Daniel的建议切换到表单,Matthias的建议放弃JS,如下所示:
首先是表单,forms.py
:
urlpatterns = [
path('', HomePageView.as_view(), name='home'),
path('questions/', QuestionsView.as_view(), name='questions'),
path('results/', ResultsView.as_view(), name='results'),
]
class QuestionsView(TemplateView):
template_name = 'questions.html'
class ResultsView(TemplateView):
template_name = 'results.html'
def answers(request):
if request.method == 'POST':
context = {}
context["age"] = request.POST['age']
context["education"] = request.POST['education']
return context
EDUCATION_CHOICES= [
('none', 'None'),
('gcse', 'GCSE'),
('alevel', 'A-level'),
('university', 'University'),
]
class UserInputForm(forms.Form):
age = forms.IntegerField(label='Enter your age')
education = forms.CharField(label='What is your highest level of education?', widget=forms.Select(choices=EDUCATION_CHOICES))
然后是表单模板,userinputform.html
:
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
<form action="/results/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
最后,results.html
:
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
<form action="/results/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
<p>Results:</p>
Age: {{ age }} <br />
Education: {{ education }}
结果:
年龄:{{Age}}
教育:{{教育}
您不能随意调用方法“answers”。它需要是“get”或“post”,在您的例子中可能是“post”;然后,您不需要检查方法中的request.method,它将始终是POST。但是,这仍然不起作用,因为您的HTML表单元素没有name
属性,因此浏览器不会为它们发送任何数据。确实,尽管整个方法应该简化为使用Django表单的单个视图;换言之,一个FormView。我同意。jQueryAjax将对结果端点进行异步调用。由于jQuery,数据应该正确地存在(即使没有name
s),但是主页不会导航或加载视图代码。这真的不需要jQuery甚至JS。我不知道是什么导致了“不允许使用方法”的错误。@Matthias这是因为ResultsView没有定义post
方法,正如我在第一条评论中提到的。你不能随意调用该方法“answers”。它需要是“get”或“post”,在您的例子中可能是“post”;然后,您不需要检查方法中的request.method,它将始终是POST。但是,这仍然不起作用,因为您的HTML表单元素没有name
属性,因此浏览器不会为它们发送任何数据。确实,尽管整个方法应该简化为使用Django表单的单个视图;换言之,一个FormView。我同意。jQueryAjax将对结果端点进行异步调用。由于jQuery,数据应该正确地存在(即使没有name
s),但是主页不会导航或加载视图代码。这真的不需要jQuery甚至JS。我不知道是什么导致了“不允许使用方法”错误。@Matthias这是因为ResultsView没有定义post
方法,正如我在第一条评论中提到的那样。