Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 制作模型搜索表单的最佳方法?_Django_Django Forms - Fatal编程技术网

Django 制作模型搜索表单的最佳方法?

Django 制作模型搜索表单的最佳方法?,django,django-forms,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.C

我有这个模型:

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)
我有一个“查找飞机”页面,用户可以在其中输入数据,用于查找符合其标准的所有飞机。例如,用户可以在文本框中输入“boeing”,在
引擎类型
框中输入“jet”,并在数据库中显示所有波音飞机。我现在这样做的方式是通过以下表格:

class AircraftSearch(ModelForm):
    search = forms.CharField(max_length=100, required=False)
    class Meta:
        model = Aircraft
        fields = ('engine_type', 'cat_class', )
然后是一个(不必要的复杂)视图,该视图将此表单中的数据转换为一组
filter()
,并将其添加到
airpair.objects.all()
。(我没有为每个CharField设置4个单独的搜索字段,而是将它们合并到一个搜索字段中。)

这一切都可行,但有一个问题。如果用户想从他们的搜索条件中排除引擎类型,那么他们就被搞定了,因为“Any”不是引擎类型字段的有效选择。我将不得不为engine type和category/class创建一个新的字段/小部件,以包含“Any”,这与首先使用模型视图的目的背道而驰

我很好奇。有更好的办法吗?这似乎是一项非常常见的任务,必须由其他人完成,但谷歌搜索不会带来任何结果。

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

通常,
ModelForm
s用于创建和编辑模型;在这种情况下,我不确定它对您的帮助是否不仅仅是做一个常规表单:

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()})

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

相反,根据您需要的字段创建一个全新的表单,并使用用户将(取消)选择的复选框禁用搜索特定字段。

当然,您仍然应该使用模型中定义的选项,只需导入文件并使用该列表即可。

问题在于“选项=引擎类型”仅包括有效选项,如“喷射”和“活塞”等,而不包括“任何”。您或者需要将该选项添加到引擎类型列表中,或者每个SearchForm将包含其中一个选项,您将被迫按特定的引擎类型进行筛选。对我来说,创建一个搜索表单并在引擎类型列表中添加“Any”选项不是问题,但我觉得它有点黑客味,如果有更好的“non-hacky”方法存在,我宁愿这样做。在我看来,对它来说,做一些类似于choices=(“”,'Any'),)+引擎类型的事情是一个相当干净的解决方案。您没有向模型中引入“any”,但它可以在表单中使用。