Сохранение нескольких GET-параметров в URL Django
В моем проекте django есть страница, отображающая список времен. На этой странице есть 3 GET формы, которые предназначены для:
Разбор страниц
Выбор данных графика
Сортировка элементов
Если пользователь должен выбрать поле во всех этих формах, URL должен выглядеть примерно так:
http://127.0.0.1:8000/watchlist/?page=1&graph_data=price&sort=quantity_desc
Но когда пользователь отправляет одну из этих форм, он сохраняет только этот GET-параметр в URL. например:
выбирает страницу = 2
http://127.0.0.1:8000/watchlist/?page=2
selects sort = quantity_asc
http://127.0.0.1:8000/watchlist/?sort=quantity_asc
Параметр страницы перезаписывается, когда оба параметра должны присутствовать в URL. Как сохранить несколько GET-параметров в URL?
views.py
def watchlist(request):
#get requests
graph_metric = request.GET.get("graph-data-options", "avg_price")
page = int(request.GET.get("page", 1))
sort_field = request.GET.get("sort-field", "avg_price-asc")
return render(request, "App/watchlist.html", context=context)
html
<!-- Page number -->
<form id="page-buttons-form" action="{% url 'watchlist' %}" method="GET">
{% for page_button in num_pages %}
<input name="page" type="submit" value="{{page_button}}">
{% endfor %}
</form>
<!-- Sort items -->
<form id="sort-form" action="{% url 'watchlist' %}" method="GET">
<label for="sort-field">Sort:</label>
<select onchange="this.form.submit()" name="sort-field">
{% for sort in sort_options %}
<option value="{{sort.value}}">{{sort.text}}</option>
{% endfor %}
</select>
</form>
<!-- Graph data -->
<form action="{% url 'watchlist' %}" method="GET">
<label for="graph-data-options">Graph Data</label>
<select onchange="this.form.submit()" name="graph-data-options">
{% for graph_option in graph_options %}
<option value="{{graph_option.value}}">{{graph_option.text}}</option>
{% endfor %}
</select>
</form>
Это пробный вариант, демонстрирующий, как можно сохранить GET-параметры при отправке различных форм. Каждая форма запускает функцию fillHiddenFields
перед отправкой, вставляя существующие параметры URL в скрытые поля.
Примечание: Очевидно, это не работает как сниппет StackOverflow, поэтому вам придется выполнить это на локальной машине.
function fillHiddenFields(event){
// extract query params from URL
const urlSearchParams = new URLSearchParams(window.location.search);
const params = Object.fromEntries(urlSearchParams.entries());
// find hidden fields in form
let form = event.target;
const hiddentElmts = form.querySelectorAll('input[type=hidden]');
// update hidden fields with URL query params
for(let elmt of hiddentElmts){
if(elmt.name in params){
elmt.value = params[elmt.name];
}
}
// console.log form data to check that hidden fields are updated
let formdata = new FormData(form);
console.log(Object.fromEntries(formdata));
}
<body>
<form id="form1" action="javascript:void(0)" method="GET" onsubmit="fillHiddenFields(event)">
<input type="text" name="field1" value="Field 1">
<input type="hidden" name="field2" value="">
<input type="submit" value="Submit">
</form>
<form id="form2" action="javascript:void(0)" method="GET" onsubmit="fillHiddenFields(event)">
<input type="hidden" name="field1" value="">
<input type="text" name="field2" value="Field 2">
<input type="submit" value="Submit">
</form>
</body>
Чтобы сохранить несколько GET-параметров в URL, вы можете включить текущие GET-параметры в атрибут action формы. Один из способов сделать это - использовать словарь request.GET для построения URL.
В вашем файле views.py вы можете изменить функцию watchlist следующим образом:
def watchlist(request):
#get requests
graph_metric = request.GET.get("graph-data-options", "avg_price")
page = int(request.GET.get("page", 1))
sort_field = request.GET.get("sort-field", "avg_price-asc")
context = {...}
context['url_params'] = request.GET.copy()
context['url_params'].pop("page", None)
return render(request, "App/watchlist.html", context=context)
Затем в своем шаблоне вы можете включить текущие параметры GET в атрибут action формы следующим образом:
<form id="page-buttons-form" action="{% url 'watchlist' %}?{% for key, value in url_params.items %}{{key}}={{value}}&{% endfor %}" method="GET">
{% for page_button in num_pages %}
<input name="page" type="submit" value="{{page_button}}">
{% endfor %}
</form>