Вы можете кодировать введенный ZIP в URL, передавать его через куки, сохранять его в переменных сеанса или использовать (скрытый) элемент ввода, который заставляет браузер пропускать его через GET и POST запрос.
Закодируйте его в URL
В этом случае мы можем переписать URL-адрес на:
url(r'^within_miles<b>/(?P<zip>[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">
<b><input type="hidden" name="zip_code" value="{{ query }}"></b>
<button type="submit">Filter</button>
</form>
Таким образом, мы добавляем элемент формы, заполняем его некоторыми данными и позволяем браузеру снова отправлять значение в следующее представление. Обратите внимание, что опять же это браузер, который делает это, поэтому пользователь может проверить DOM (большинство браузеров позволяют это, и впоследствии редактировать его).
Использование переменных сеанса и / или куки
Вы также можете принять решение об использовании переменных сеанса (хранящихся на стороне сервера, поэтому «безопасных») или файлов cookie (хранящихся на стороне клиента, которые могут быть изменены). Однако потенциальная проблема заключается в том, что они хранятся в браузере, и изменения в файлах cookie на одной вкладке, таким образом, могут повлиять на другую вкладку. Кроме того, файлы cookie и сеансы будут «умирать» после запроса и, следовательно, могут создать много проблем в будущих представлениях.
Вы можете установить переменную сеанса в представлении с помощью:
request.<b>session['zip_code'] = query</b>
Таким образом, будет сохранена запись на стороне сервера, так что другой вызов сможет снова получить это значение. request.session
действует как словарь, который поддерживает некое состояние за сеанс.
установка и получение переменных сеанса
В другом представлении вы можете запросить request.session
, например:
zip_code = request.<b>session.get('zip_code')</b>
настройка и получение куки
Мы можем использовать аналогичный подход с файлами cookie. Однако браузер может отклонить файлы cookie или манипулировать ими, поэтому нет особых гарантий, что данные не будут подделаны (фактически их нет). Вы можете установить cookie с помощью:
response = render (запрос, 'core / search.html', {'query': query, 'jobs_matching_query': jobs_matching_query, 'number_of_results': number_of_results})
response.set_cookie ( 'zip_code', запрос)
обратный ответ
Прежде чем мы, таким образом, возвращаем результат render(..)
, мы вызываем .set_cookie(..)
для результата.
Мы можем - например, в более позднем виде - получить содержимое с помощью:
zip_code = request.<b>COOKIES.get('zip_code')</b>
Улучшение job_query
вида
Представление job_query
, однако, выглядит немного странно: оно использует все виды «необычных» практик кода. Например, число элементов рассчитывается путем итерации по нему вместо взятия len(..)
. Это также выглядит в основном как ListView
[Django-doc] , и мы можем сделать запрос более элегантным, используя Q
-объекты [Django-документ] . Тогда список выглядит так:
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()
результат в качестве ссылки.