我有这个型号:
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”,这种方式首先打败了使用模型视图的目的
我很好奇。有没有更好的办法?这似乎是一项非常普遍的任务,必须由其他人解决,但谷歌搜索没有任何结果。
答案 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使用的是数据操作,而不是它的搜索。
相反,根据您需要的字段和用户将(取消)选择禁用搜索特定字段的复选框创建一个全新的表单。
当然,您仍然应该使用模型中定义的选项,只需导入文件并使用该列表。