jus*_*tin 2 django django-forms django-views
摘要:我正在尝试建立一个工作站点。在 index.html 上,用户在表单中输入邮政编码以查看该邮政编码中的工作,此表单由job_query视图处理。这会将他们带到另一个页面(search.html),在那里起初您只能看到该特定邮政编码中的工作,但我正在尝试添加一个过滤器,让用户可以看到 X 英里内的工作。如何将在 index.html 上的 from 中输入的邮政编码值传递到下一页?
索引.html:
<h2>Find a Job</h2>
<!--Search Bar-->
<form method = "GET" action = "{% url 'search' %}" >
<div id = "form_grid">
<input name="query" type="text" placeholder="Zip Code">
<button type="submit">Search</button>
</div>
</form>
Run Code Online (Sandbox Code Playgroud)
搜索.html:
<form method = "GET" action = "{% url 'search' %}" >
<input class="search_bar" name="query" type="text" placeholder="Zip Code">
<button class="search_btn btn btn-outline-success " type="submit">Find Jobs</button>
</form>
<form id="within_miles_form" method = "GET" action = "{% url 'within_miles' %}" >
<input class="search_bar" name="miles" type="text" placeholder="Within X miles of Zip Code">
<button type="submit">Filter</button>
</form>
<!--code to display jobs-->
Run Code Online (Sandbox Code Playgroud)
视图.py:
def job_query(request):
if request.method == "GET":
query = request.GET.get('query')
jobs_matching_query = Job.objects.filter(zip_code__iexact = query) | Job.objects.filter(city__iexact=query) | Job.objects.filter(state__iexact=query)
number_of_results = 0
for job in jobs_matching_query:
number_of_results = number_of_results + 1
return render(request, 'core/search.html', {'query': query ,'jobs_matching_query': jobs_matching_query, 'number_of_results': number_of_results})
def within_miles(request):
miles = request.GET['miles']
#how can i use value of the zip code entered?
Run Code Online (Sandbox Code Playgroud)
网址.py:
url(r'^search$', views.job_query, name="search"),
url(r'within_miles', views.within_miles, name="within_miles"),
Run Code Online (Sandbox Code Playgroud)
我想我包含了所有相关信息,但如果我遗漏了什么,请告诉我,在此先感谢您的帮助。
您可以在 URL 中对输入的 ZIP进行编码,通过 cookie 传递它,将其存储在会话变量中,或者使用(隐藏的)输入元素强制浏览器通过 GET 和 POST 请求传递它。
在这种情况下,我们可以将 URL 重写为:
url(r'^within_miles/(?P<zip>[0-9]{5})/$', views.within_miles, name="within_miles"),Run Code Online (Sandbox Code Playgroud)
所以现在不能再取了your.domain.com/within_miles,但是your.domain.com/within_miles/12345。它使用户可以轻松地“操纵” URL,但由于用户可能可以提供任何 ZIP,因此保护它可能没有太大好处。
在表单中,生成的 URL 是这样的:
{% url 'within_miles' zip=query %}Run Code Online (Sandbox Code Playgroud)
(您可以使用另一个更严格的邮政编码变量)
因此,您应该确保query这里是一个五位数的字符串(或以其他方式更改url(..)部分中的表达式,使其允许所有可能的查询)。
我们还可以在隐藏的表单元素中编码内容,例如在这里我们可以在表单中创建一个元素:
<form id="within_miles_form" method = "GET" action = "{% url 'within_miles' %}" >
<input class="search_bar" name="miles" type="text" placeholder="Within X miles of Zip Code">
<input type="hidden" name="zip_code" value="{{ query }}">
<button type="submit">Filter</button>
</form>Run Code Online (Sandbox Code Playgroud)
因此,我们添加了一个表单元素,用一些数据填充它,然后让浏览器再次将值提交给下一个视图。请注意,再次是浏览器执行此操作,因此用户可以检查 DOM(大多数浏览器允许这样做,然后对其进行编辑)。
您还可以决定使用会话变量(存储在服务器端,因此“安全”)或 cookie(存储在客户端,可以被篡改)。然而,一个潜在的问题是这些存储在浏览器中,并且对一个标签页中的 cookie 进行了更改,因此可能会影响另一个标签页。此外,cookies 和 session 会在请求后“消亡”,因此会在未来的视图中造成很多麻烦。
您可以在视图中设置会话变量:
request.session['zip_code'] = queryRun Code Online (Sandbox Code Playgroud)
因此,这将在服务器端存储一个条目,以便另一个调用可以再次检索该值。这request.session就像一本字典,每个会话都保存某种状态。
在另一个视图中,您可以因此查询request.session,例如:
zip_code = request.session.get('zip_code')Run Code Online (Sandbox Code Playgroud)
我们可以对 cookie 使用类似的方法。然而,浏览器可能会拒绝 cookie 或操纵它们,因此没有太多保证不会篡改数据(实际上没有)。您可以通过以下方式设置 cookie:
response = render(request, 'core/search.html', {'query': query ,'jobs_matching_query': jobs_matching_query, 'number_of_results': number_of_results})
response.set_cookie('zip_code', query)
return responseRun Code Online (Sandbox Code Playgroud)
在我们返回 的结果之前render(..),我们调用.set_cookie(..)结果。
我们可以 - 例如在稍后的视图中 - 检索内容:
zip_code = request.COOKIES.get('zip_code')Run Code Online (Sandbox Code Playgroud)
job_query视野job_query然而,该视图看起来有点奇怪:它使用了各种“不常见”的代码实践。例如,元素的数量是通过迭代它来计算的,而不是取len(..). 这也基本上看起来像一个ListView[Django-doc],我们可以通过使用Q-objects [Django-doc]使查询更加优雅。列表视图看起来像:
def JobListView(ListView):
model = Job
context_object_name = 'jobs_matching_query'
template_name = 'core/search.html'
def get_context_data(self, **kwargs):
kwargs = super(JobListView, self).get_context_data(**kwargs)
kwargs.update(
number_of_results=len(kwargs['object_list'],
query = self.request.GET.get('query')
)
return kwargsRun Code Online (Sandbox Code Playgroud)
在视图中,您然后不传递JobListView,而是将JobListView.as_view()结果作为参考传递。