迭代django表单结果(不在模板中)

时间:2015-02-02 18:35:41

标签: python django

我正在尝试迭代表单结果,我无法帮助,但我认为我在这里重新发明轮子。

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"对于作者和"神秘"对于这种类型,它的工作方式与我想要的完全一样,只有两者都是真实的结果。

所以,我试图通过迭代表单结果来消除空的东西。就像我说的那样,我可能会在这里重新发明轮子。

3 个答案:

答案 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