如何在Django中提交表单时保留现有的查询字符串?

时间:2018-05-10 05:01:53

标签: python html django

我正在使用ListView,其中包含过滤器表单和搜索表单,如In a Django template, how to specify a dictionary key which is itself an attribute?中所述。当我提交搜索查询时,我希望它保留现有的过滤查询。

之前,我通过使用自定义过滤器<input>添加valuerequest.GET获取的隐藏get元素来实现此功能,该过滤器调用{{1}我的QueryDict方法。我发现这个问题是对于get s,例如,如果选择了多个选项,则只保留一个,因为MultipleChoiceField方法只返回 last 价值如https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.QueryDict.get中所述。

我现在正尝试不同的方法。使用自定义过滤器get

relative_url

和自定义过滤器from django import template from django.utils.http import urlencode from django.http import QueryDict register = template.Library() @register.simple_tag def relative_url(field_name, value, query_string=None): """ Replace the key 'field_name' in the query_string with the given value. For example, relative_url('guide', 1, 'q=Christine') == '?q=Christine&guide=1' (After https://simpleisbetterthancomplex.com/snippet/2016/08/22/dealing-with-querystring-parameters.html) """ url = urlencode({field_name: value}) if query_string: query_dict = QueryDict(query_string, mutable=True) query_dict[field_name] = value url = query_dict.urlencode() return '?' + url

referer_query

我尝试按如下方式修改搜索表单:

from urllib.parse import urlparse
from django import template

register = template.Library()


@register.filter
def referer_query(request):
    return urlparse(request.META.get('HTTP_REFERER')).query

当您按Enter键时,有一些Javascript代码提交表单(无需按提交按钮):

{% load relative_url %}
{% load referer_query %}


<form action="{% relative_url "q" search_form.q.value.strip|default:'' request|referer_query %}" method="get" class="left search col s6 hide-on-small-and-down" novalidate>
  <div class="input-field">
    <input id="search" placeholder="{{ placeholder }}"
        autocomplete="off" type="search" name="q"
        value="{{ search_form.q.value.strip|default:'' }}"
        data-query="{{ search_form.q.value.strip|default:'' }}">
    <label for="search" class="active"><i class="material-icons search-icon">search</i></label>
    <i data-behavior="search-clear"
        class="material-icons search-icon"
        {% if not search_form.q.value %}style="display: none;"{% endif %}>close</i>
  </div>
</form>

问题在于,当我通过选择过滤器并输入搜索查询来尝试此操作时,如下图所示,

enter image description here

当我在视图的 $(document).on('click', '[data-behavior="search-clear"]', function(e) { $('#search').val('').parents('form').submit(); }); $(function() { setSearchClearVisibility($('#search')); }); $(document).on('keydown', '#search', function(e) { var $el = $(this); setTimeout(function() { setSearchClearVisibility($el); }, 10); }); function setSearchClearVisibility(el) { if (el.val() === '') { $('[data-behavior="search-clear"]').hide(); } else { $('[data-behavior="search-clear"]').show(); } } $(document).on('keydown', '#search', function(e) { var $el = $(this); setTimeout(function() { if (e.keyCode !== 27) return; $('#search').val('').blur(); setSearchClearVisibility($el); if ($el.data('query') !== '') { $('#search').parents('form').submit(); } }, 10); }); 方法中放入调试器时,我发现get仅包含搜索查询,而不包含过滤器查询,尽管request.GET确实显示了过滤查询:

request.META['HTTP_REFERER']

简而言之,似乎ipdb> request.GET <QueryDict: {'q': ['Christine']}> ipdb> request.META.get('HTTP_REFERER') 'http://localhost:8000/dashboard/families?q=&guide=6&guide=4&next_outreach=&vip=&app=' 仅由表单中的request.GET元素决定,而不是由包含其他查询参数的表单<input>决定。

如何让action包含request.GET包含的查询?

(我注意到这个blog post描述了类似问题的解决方案,但代码片段看起来有点意大利面条,我认为必须有一个更简单的方法。)

1 个答案:

答案 0 :(得分:0)

我终于通过在filter_form中加入隐藏search_form来解决问题。所以在_search.html中,<form>代码中添加了

  {% for field in filter_form %}
    {{ field.as_hidden }}
  {% endfor %}

这使用了字段的as_hidden属性。