摘要:我正在尝试建立一个工作现场。用户在index.html上将邮政编码输入表单,以查看该邮政编码中的作业,该表单由job_query
视图处理。这将它们带到另一个页面(search.html),首先您只看到该特定邮政编码中的工作,但是我试图添加一个过滤器,使用户可以查看X英里内的工作。如何将在index.html上的from中输入的邮政编码值传递给下一页?
index.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>
search.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-->
views.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?
urls.py:
url(r'^search$', views.job_query, name="search"),
url(r'within_miles', views.within_miles, name="within_miles"),
我想我已经包括了所有相关信息,但是如果我缺少什么,请让我知道,在此先感谢您的帮助。
答案 0 :(得分:2)
您可以在网址中编码输入的ZIP,通过Cookie传递,将其存储在会话变量中,或使用(隐藏的)输入元素强制浏览器通过GET传递和POST请求。
在这种情况下,我们可以将URL重写为:
url(r'^within_miles/(?P<zip>[0-9]{5})/$', views.within_miles, name="within_miles"),
因此,现在不再可以获取your.domain.com/within_miles
,而只能获取your.domain.com/within_miles/12345
。这使用户可以轻松地“操纵” URL,但是由于用户可能可以提供任何ZIP,因此保护该URL可能没有太多好处。
因此,在表单中,生成的URL是:
{% url 'within_miles' zip=query %}
(您可以使用另一个更严格的邮政编码变量)
因此,您应该确保query
是一个五位数的字符串(或者更改url(..)
部分中的表达式,以便允许所有可能的查询)。
我们还可以使用 hidden 形式的元素对内容进行编码,例如,在这里我们可以创建以下形式的元素:
<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>
因此,我们添加了一个form元素,用一些数据填充它,然后让浏览器再次将值提交给下一个视图。请注意,再次由浏览器执行此操作,因此用户可以检查DOM(大多数浏览器允许这样做,然后对其进行编辑)。
您还可以决定使用会话变量(存储在服务器端,因此是“安全的”)或cookie(存储在客户端,可以被篡改)。但是,潜在的问题是这些存储在浏览器中,并且更改了一个选项卡页面中的cookie,因此可能在另一选项卡页面中起作用。此外,cookie和会话将在请求后“消失”,从而在以后的视图中造成很多麻烦。
您可以使用以下方法在视图中设置会话变量:
request.session['zip_code'] = query
因此,这将在服务器端存储一个条目,以便另一个调用可以再次检索该值。 request.session
就像一个字典,在每个会话中保持某种状态。
在另一个视图中,您可以查询request.session
,例如:
zip_code = request.session.get('zip_code')
我们可以对Cookie使用类似的方法。但是,浏览器可能会拒绝Cookie或对其进行操作,因此并不能保证没有篡改数据(实际上没有篡改数据)。您可以使用以下方法设置Cookie:
响应=渲染(请求,“ core / search.html”,{“ query”:query,“ jobs_matching_query”:jobs_matching_query,“ number_of_results”:number_of_results}) response.set_cookie(“邮政编码”,查询) 返回响应
在我们返回render(..)
的结果之前,我们先对结果调用.set_cookie(..)
。
我们可以-例如在以后的视图中-通过以下方式检索内容:
zip_code = request.COOKIES.get('zip_code')
job_query
视图然而,job_query
视图看起来有些奇怪:它使用了各种“不常见”的代码实践。例如,元素数量是通过对其进行 iteration 而不是使用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 kwargs
然后,在视图中,您不会通过JobListView
,而是将JobListView.as_view()
的结果作为参考。