How to pass data from one view to the next

时光总嘲笑我的痴心妄想 提交于 2019-12-06 09:42:17

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.

Encode it in the 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"),

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.

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)

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

Using hidden form elements

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>

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

Using session variables and/or cookies

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

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.

setting and obtaining session variables

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

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

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

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')

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!