python - 在 Django 中一次提交两个表单
问题描述
我正在研究一种ListView
包括两种形式的方法,一种是搜索形式,一种是过滤形式。这两种形式最终都会queryset
通过其get_queryset
方法改变视图。我想让它在您搜索某些内容时保持过滤器,反之亦然。
它或多或少可以工作,但仍然存在一个错误:每当我搜索某些内容时,会出现一个不应该存在的“清除过滤器”按钮:
在模板中,搜索表单包含如下:
{% block search_form %}
{% with action='dashboard:families' placeholder='Search Families' %}
{% include '_search.html' %}
{% endwith %}
{% endblock %}
_search.html
在哪里
{% load get %}
<form action="{% url action %}" 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>
{% if filter_form %}
{% for field in filter_form %}
<input type="hidden" name="{{ field.name }}" value="{{ request.GET|get:field.name }}"/>
{% endfor %}
{% endif %}
</form>
并且自定义过滤器get
只是实现了该dict.get
方法:
from django import template
register = template.Library()
@register.filter
def get(dictionary, key):
return dictionary.get(key)
简而言之,搜索表单包括一个隐藏的filter_form
,它与搜索查询一起提交。
包含过滤器表单的模板部分内容如下:
<form action={% url 'dashboard:families' %} method="GET" data-behavior="filters">
<input type="hidden" name="q" value="{{ request.GET.q.strip }}"/>
<div class="input-field col s2">
{{ filter_form.guide }}
<label class="active">Guide</label>
{% if filter_form.is_guide_filled %}
<a href="" class="clear"><i class="material-icons tiny">clear</i></a>
{% endif %}
</div>
<div class="input-field col s2">
{{ filter_form.status }}
<label class="active">Status</label>
{% if filter_form.is_status_filled %}
<a href="" class="clear"><i class="material-icons">clear</i></a>
{% endif %}
</div>
<div class="input-field col s2">
{{ filter_form.package }}
<label class="active">Company / Package</label>
{% if filter_form.is_package_filled %}
<a href="" class="clear"><i class="material-icons tiny">clear</i></a>
{% endif %}
</div>
<div class="input-field col s2">
{{ filter_form.next_outreach }}
<label>Outreach</label>
{% if filter_form.is_next_outreach_filled %}
<a href="" class="clear"><i class="material-icons tiny">clear</i></a>
{% endif %}
</div>
<div class="input-field col s2">
{{ filter_form.country }}
<label class="active">Country</label>
{% if filter_form.is_country_filled %}
<a href="" class="clear"><i class="material-icons tiny">clear</i></a>
{% endif %}
</div>
<div class="input-field col s1">
{{ filter_form.vip }}
<label>VIP</label>
{% if filter_form.is_vip_filled %}
<a href="" class="clear"><i class="material-icons tiny">clear</i></a>
{% endif %}
</div>
<div class="input-field col s1">
{{ filter_form.app }}
<label>App</label>
{% if filter_form.is_app_filled %}
<a href="" class="clear"><i class="material-icons tiny">clear</i></a>
{% endif %}
</div>
<a href="{% url 'dashboard:families' %}?q={{ request.GET.q.strip }}"
data-behavior="clear-filters"
class="btn-flat" {% if not filter_form.is_filled %}style="display: none;"{% endif %}>
<i class="material-icons">close</i>Clear Filters
</a>
</form>
请注意,过滤器表单还包含一个以q
搜索查询命名的隐藏字段。由于这是 a ,因此将其设置为CharField
是有意义的。value
request.GET.q.strip
问题是,如果我进入调试器FamilyFilterForm
,我会看到表单的数据是我期望的“字符串化”版本:
ipdb> self.data
<QueryDict: {'q': ['Christine'], 'status': ['None'], 'next_outreach': [''], 'country': ['None'], 'vip': [''], 'app': [''], 'guide': ['6'], 'package': ['None']}>
请注意如何将None
值转换为字符串'None'
。这会导致is_filled
过滤器表单的属性“认为”一个值已被填写,而实际上并没有。
相反,我想让表单的数据等同于
ipdb> from django.http import QueryDict
ipdb> query_dict = QueryDict('q=Christine&guide=6')
ipdb> query_dict.dict()
{'q': 'Christine', 'guide': '6'}
特别是,如果没有应用过滤器,它应该只是一个空的QueryDict()
or {}
。
当以这种方式在模板中传递时,如何避免request.GET
值被“字符串化” ?value
解决方案
我设法通过使用字段的属性正确地包含了隐藏filter_form
(正确表示了多项选择字段) 。as_hidden
所以_search.html
模板变成了
<form action="{% url action %}" 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>
{% for field in filter_form %}
{{ field.as_hidden }}
{% endfor %}
</form>
同样,过滤器形式包含
{{ search_form.q.as_hidden }}
持久化搜索查询。
推荐阅读
- ruby-on-rails - Rails form_with select selected option
- eclipse - Eclipse Marketplace Install pending
- c# - Why doesn't "OnTriggerEnter2D()" work when two specific objects collide?
- javascript - 如何在 NodeJS 中导入、导出和合并多个 GraphQL 类型定义
- java - 直接递归与 While 循环的时间复杂度性能
- machine-learning - 平均绝对误差的偏导数
- php - 有没有办法在 OOP/PHP 中转储方法定义?
- ios - 当应用程序处于前台时,适用于 iOS 的 Flutter FCM 推送通知
- javascript - Chartjs:同一标签的多个数据值
- node.js - node_modules/.cache/babel-loader 文件夹中有数千个文件是否正常?