【问题标题】:How to pass data from one view to the next如何将数据从一个视图传递到下一个视图
【发布时间】:2018-09-16 20:28:50
【问题描述】:

总结:我正在尝试建立一个工作网站。在 index.html 上,用户将邮政编码输入到表单中以查看该邮政编码中的工作,此表单由 job_query 视图处理。这会将他们带到另一个页面(search.html),起初您只能看到该特定邮政编码中的工作,但我正在尝试添加一个过滤器,让用户可以看到 X 英里内的工作。如何将 index.html 中输入的邮政编码值传递到下一页?

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>

搜索.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"),

我想我包含了所有相关信息,但如果我遗漏了什么,请告诉我,提前感谢您的帮助。

【问题讨论】:

  • 您可以在 URL 中对其进行编码。话虽如此,这里的视图包含一些“奇怪”的编码风格。
  • 是的,这是我尝试构建的更复杂的项目之一,我觉得我把它弄得太复杂了

标签: django django-forms django-views


【解决方案1】:

您可以在 URL 中编码输入的 ZIP,通过 cookie 传递它,将其存储在会话变量中,或者使用(隐藏)输入元素强制浏览器通过 GET 传递它和 POST 请求。

在 URL 中编码

在这种情况下,我们可以将 URL 重写为:

url(r'^within_miles<b>/(?P&lt;zip&gt;[0-9]{5})</b>/$', views.within_miles, name="within_miles"),

所以现在不能再获取your.domain.com/within_miles,而是your.domain.com/within_miles/12345。它使用户可以轻松“操纵” URL,但由于用户可能提供任何 ZIP,因此保护它可能没有太多好处。

在表单中,生成的 URL 是这样的:

{% url 'within_miles' <b>zip=query</b> %}

(您可以使用另一个更严格地是邮政编码的变量)

因此,您应该确保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>

我们因此添加了一个表单元素,用一些数据填充它,然后让浏览器再次将值提交到下一个视图。请注意,再次执行此操作的是浏览器,因此用户可以检查 DOM(大多数浏览器允许这样做,然后对其进行编辑)。

使用会话变量和/或cookies

您还可以决定使用会话变量(存储在服务器端,因此“安全”)或 cookie(存储在客户端,可以被篡改)。然而,一个潜在的问题是这些存储在浏览器中,并且对一个标签页中的 cookie 进行更改,因此可能会在另一个标签页中产生影响。此外,cookie 和会话将在请求后“消亡”,从而在以后的视图中造成很多麻烦。

您可以在视图中设置会话变量:

request.<b>session['zip_code'] = query</b>

这将因此在服务器端存储一个条目,以便另一个调用可以再次检索该值。 request.session 就像一个字典,保持某种状态 per 会话。

设置和获取会话变量

在另一个视图中,您可以查询request.session,例如:

zip_code = request.<b>session.get('zip_code')</b>

设置和获取cookies

我们可以对 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 response

在我们返回render(..)的结果之前,我们在结果上调用.set_cookie(..)

我们可以 - 例如在以后的视图中 - 检索内容:

zip_code = request.<b>COOKIES.get('zip_code')</b>

改进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 kwargs

在视图中,您不会传递JobListView,而是传递JobListView.as_view() 结果作为参考。

【讨论】:

    猜你喜欢
    • 2021-11-09
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多