【问题标题】:How to preserve the existing query string when submitting a form in Django?在Django中提交表单时如何保留现有的查询字符串?
【发布时间】:2018-10-20 07:19:53
【问题描述】:

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

以前,我通过添加隐藏的<input> 元素来实现这一点,其中value 是使用自定义过滤器getrequest.GET 获得的,该过滤器调用QueryDictget 方法。我发现这样做的问题是,对于MultipleChoiceFields,例如,如果选择了多个选项,则只保留一个,因为get 方法只返回 last 值,如中所述https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.QueryDict.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

我尝试将搜索表单修改如下:

{% 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>

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

  $(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 似乎仅由表单中的 &lt;input&gt; 元素确定,而不是由包含附加查询参数的表单的 action 确定。

如何使request.GET 包含HTTP_REFERER 包含的查询?

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

【问题讨论】:

    标签: python html django


    【解决方案1】:

    我终于通过在search_form 中包含一个隐藏的filter_form 解决了这个问题。所以在_search.html&lt;form&gt; 标签内,我添加了

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

    这利用了该字段的as_hidden 属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-07
      • 2020-02-08
      相关资源
      最近更新 更多