我正在尝试迭代表单结果,我无法帮助,但我认为我在这里重新发明轮子。
filterlist = []
if request.POST:
form = FilterForm(request.POST)
if form.is_valid():
for key, value in form.cleaned_data.iteritems():
filterlist.append(key)
filterlist.append(value)
这很有效,但看起来很尴尬并且会产生很多其他问题。例如,这些值会以u'所以我必须使用value.encode(" utf8")但是如果值为None则会引发错误。所以现在我必须检查它是否为None,如果不是则编码。一定有更好的方法。
编辑:我想做什么。
我正在尝试过滤页面上显示的内容。我遇到的问题是,如果一个值是空的(用户不填充该框,因为他们只想过滤一个对象),那么我没有得到任何结果。例如,用户想要按作者姓名搜索所有书籍" Smith"但是不想搜索某种类型。
results = Books.objects.filter(author=author, genre=genre)
用户无法获得结果,因为这是一个AND搜索。但是,如果用户输入" Smith"对于作者和"神秘"对于这种类型,它的工作方式与我想要的完全一样,只有两者都是真实的结果。
所以,我试图通过迭代表单结果来消除空的东西。就像我说的那样,我可能会在这里重新发明轮子。
答案 0 :(得分:2)
如果模型和表单中的字段名称相同,请尝试以下操作:
filter = {}
if request.method == 'POST':
form = FilterForm(request.POST)
if form.is_valid():
for key, value in form.cleaned_data.iteritems():
if value:
filter[key] = value
results = Books.objects.filter(**filter)
Python是少数具有命名参数的语言之一。您可以使用非空表单字段组合dict,并使用kwargs
解包运算符**
将其传递给过滤器方法。
例如:
kwargs = {"author": "Freud"}
results = Books.objects.filter(**kwargs)
与:
相同results = Books.objects.filter(author="Freud")
答案 1 :(得分:0)
我认为问题是默认情况下,如果表单字段没有用户输入的值,则表单字段无效,如果您不需要每次都需要该字段,则需要设置所需的字段forms.py中的ModelForm类中的字段为false,如下面的代码所示。请记住,该字段仅在不在模型本身的模型表单中设置为false
class myForm(forms.ModelForm):
myfield_id = forms.CharField(required=False)
myfield_foo = forms.CharField(required=False)
myfield_bar = forms.CharField(required=False)
myfield_name = forms.CharField(required=False)
class Meta:
model = myModel
exclude = ('myfield_ex','myfield_file')
fields = ['myfield_id','myfield_foo','myfield_bar','myfield_name',]
在您输入用户输入的表单后,您需要使用Q对象,该对象可用于创建复杂查询,如此处的manula页面所述 https://docs.djangoproject.com/en/1.7/topics/db/queries/#complex-lookups-with-q
一个简单的示例代码看起来像
if form.is_valid():
qgroup = []
for key,value in form.cleaned_data.iteritems():
if value:
q_name = Q(**{"%s"%format(filterKey[key]) : value})
qgroup.append(q_name)
q = None
# can use the reduce as shown here qgroup = reduce(operator.or_, (Q(**{"{0}".format(filterKey[key]): value}) for (key,value) in form.cleaned_data.iteritems()))
for key,value in form.cleaned_data.iteritems():
if value:
q_name = Q(**{"%s"%format(filterKey[key]) : value})
qgroup.append(q_name)
for x in qgroup:
q &= x ### Or use the OR operator or
if q:
resultL = myModel.objects.filter(q).select_related()
filterKey可以在
的行上看到 filterKey = {'myfield_id' : "myfield_id",
'myfield_foo' : "myfield_foo__icontains",
'myfield_bar' : "myfield_bar__relative_field__icontains",
}
答案 2 :(得分:0)
在Python 3中使用:
HTTP