如何将数据从一个视图传递到下一个视图 [英] How to pass data from one view to the next

查看:115
本文介绍了如何将数据从一个视图传递到下一个视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Summary: I am trying to build a job site. On index.html the user enters a zip code into a form to see jobs in that zip code, this form is handled with the job_query view. This brings them to another page(search.html) where at first you only see jobs in that specific zip code but I am trying to add a filter that lets the user see jobs within X miles. How can I pass the zip code value entered in the from on index.html to the next page?

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>

search.html:

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"),

我想我已经包括了所有相关信息,但是如果我错过了什么,请让我知道,在此先感谢任何帮助。

I think I included all the relevant info but if I am missing something please let me know, thanks in advance for any help.

推荐答案

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

You can encode the entered ZIP in a URL, pass it through cookies, store it in the session variables, or use a (hidden) input element that forces the browser to pass it through a GET and POST request.

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

In that case we can rewrite the URL to:

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,因此保护该ZIP可能没有太多好处。

So now one can no longer fetch your.domain.com/within_miles, but your.domain.com/within_miles/12345. It makes it easy for a user to "manipulate" the URL, but since the user can probably provide any ZIP, there is probably not much gain to protect that.

在表单中,因此生成的URL为:

In the form, the URL that is generated is thus:

{% url 'within_miles' zip=query %}

(您可以使用更严格的邮政编码变量)

(you can use another variable that is more strictly a ZIP code)

因此,应确保 query 为这里是一个五位数的字符串(或者更改 url(..)部分中的表达式,以便允许所有可能的查询)。

You should thus ensure that query is here a five digit string (or otherwise change the expression in the url(..) part such that it allows all possible queries).

我们还可以使用 hidden 表单元素对内容进行编码,例如,在此处我们可以在格式:

We can also encode content in hidden form elements, for example here we can create an element in the 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">
    <input type="hidden" name="zip_code" value="{{ query }}">
    <button type="submit">Filter</button>
</form>

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

We thus add a form element, fill it with some data, and let the browser submit the value again to the next view. Note that again it is the browser that does this, so a user can inspect the DOM (most browsers allow that, and subsequently edit it).

您还可以决定使用会话变量(存储在服务器端,因此是安全的)或cookie(存储在客户端) ,可以进行篡改)。但是,潜在的问题是这些存储在浏览器中,并且更改了一个选项卡页面中的cookie,因此可能在另一选项卡页面中起作用。此外,Cookie和会话将在死亡时死。

You can also decide to use session variables (stored at server side, so "secure") or cookies (stored at client side, can be tampered with). A potential problem however is that these are stored in the browser, and changes to the cookies in one tab page, thus can have effect in the other tab page. Furthermore cookies and sessions will "die" after the request, and thus can create a lot of trouble in future views.

您可以在视图中设置会话变量,方法如下:

You can set a session variable in the view with:

request.session['zip_code'] = query

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

This will thus store an entry at the server side such that another call can retrieve that value again. The request.session acts like a dictionary that keeps some sort of state per session.

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

In another view, you can thus query the request.session, like:

zip_code = request.session.get('zip_code')


< h2>设置并获取cookie

我们可以对cookie使用类似的方法。但是,浏览器可能会拒绝cookie或对其进行操作,因此并不能保证没有篡改数据(实际上没有篡改数据)。您可以通过以下方式设置Cookie:

setting and obtaining cookies

We can use a similar approach with cookies. A browser however might reject cookies, or manipulate them, so there are not that much guarantees that there is no tampering with the data (in fact there are none). You can set a cookie with:

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(..)

Before we thus return the result of render(..), we call .set_cookie(..) on the result.

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

We can - for example in a later view - retrieve the content with:

zip_code = request.COOKIES.get('zip_code')


改进 job_query 视图


job_query 视图看起来有点奇怪:它使用了各种的不常见代码实践。例如,元素数量是通过在其上进行 iteration 而不是使用 len(..)来计算的。这基本上看起来像是 ListView [Django-doc] ,我们可以使用 Q -对象[Django-doc] 。列表视图如下所示:

Improving the job_query view

The job_query view however looks a bit strange: it uses all kinds of "uncommon" code practices. For example the number of elements is calculated by iterating over it, instead of taking the len(..). This also looks basically like a ListView [Django-doc] and we can make the query more elengant by using Q-objects [Django-doc]. The listview then looks like:

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()结果作为参考。

In the view, you then not pass the JobListView, but JobListView.as_view() result as a reference.

这篇关于如何将数据从一个视图传递到下一个视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆