制作模型搜索表​​单的最佳方法是什么?

时间:2009-07-10 03:28:37

标签: django django-forms

我有这个型号:

class Aircraft(models.Model):
    model       =   models.CharField(max_length=64, blank=True)
    type        =   models.CharField(max_length=32)
    extra       =   models.CharField(max_length=32, blank=True)
    manufacturer    =   models.CharField(max_length=32)
    engine_type =   models.IntegerField("Engine Type", choices=ENGINE_TYPE, default=0)
    cat_class   =   models.IntegerField("Category/Class", choices=CAT_CLASSES, default=1)

我有一个“查找飞机”页面,向用户显示一个表格,在表格中他们可以输入数据,用于查找符合其标准的所有飞机。例如,用户可以将“波音”输入到文本框中并“喷射”到engine_type框中,它将显示数据库中的所有波音喷气机。我现在这样做的方式是这种形式:

class AircraftSearch(ModelForm):
    search = forms.CharField(max_length=100, required=False)
    class Meta:
        model = Aircraft
        fields = ('engine_type', 'cat_class', )

然后是一个(不必要的复杂)视图,它将此表单中的数据转换为一组filter(),并将其添加到Aircraft.objects.all()。 (我没有为每个CharField提供4个单独的搜索字段,而是将它们全部合并到一个搜索字段中。)

这一切都有效,但有一个问题。如果用户想要从他们的搜索条件中排除引擎类型,那么他们就会被搞砸,因为“Any”不是引擎类型字段的有效选择。我将不得不为引擎类型和类别/类创建一个新的字段/小部件以包含“Any”,这种方式首先打败了使用模型视图的目的

我很好奇。有没有更好的办法?这似乎是一项非常普遍的任务,必须由其他人解决,但谷歌搜索没有任何结果。

2 个答案:

答案 0 :(得分:8)

在功能上,“任何”都可以通过在过滤中不包括特定搜索向量来实现。

通常,ModelForm用于创建和编辑模型;在这种情况下,我不确定它对你的帮助远远超过了常规形式:

class AircraftSearch(forms.Form):
    search = forms.CharField(max_length=100, required=False)
    engine_type = forms.ChoiceField(choices=ENGINE_TYPE)
    cat_class = forms.ChoiceField(choices=CAT_CLASS)

要进行搜索,只需在字段非空时进行过滤:

def search(request):
    if request.method == 'POST':
        results = Aircraft.objects.all()

        search = request.POST.get('search', None)
        if search:
            results = results.filter(Q(model=search)|Q(type=search)|Q(extra=search)|Q(manufacturer=search))

        engine_type = request.POST.get('engine_type', None)
        if engine_type:
            results = results.filter(engine_type=engine_type)

        cat_class = request.POST.get('cat_class', None)
        if cat_class:
            results = results.filter(cat_class=cat_class)

        return render_to_response('aircraft.html', {'form': AircraftSearch(request.POST), 'aircraft': results})

    return render_to_response('aircraft.html', {'form': AircraftSearch()})

答案 1 :(得分:3)

我认为你不应该使用ModelForm 典型的ModelForm使用的是数据操作,而不是它的搜索。

相反,根据您需要的字段和用户将(取消)选择禁用搜索特定字段的复选框创建一个全新的表单。
当然,您仍然应该使用模型中定义的选项,只需导入文件并使用该列表。