0

我有一个这样的模型

class Customer(models.Model):
    #fields
    doctor = models.ForeignKey(Doctor)

我想创建一个搜索客户表单,所以我创建了一个新表单(不是 ModelForm,因为我只想要表单的字段而不是保存方法),其中包含客户的字段。我想要实现的功能是:

  • 如果表单为空并且用户按搜索显示所有客户
  • 如果表单具有包含数据的字段,请使用字段进行 AND 搜索

我为测试目的实现的搜索字段是以下 first_name、last_name 和医生。我使用了这样的 Q 对象:

if customer_form.is_valid():
    post_data = customer_form.cleaned_data
    customers = Customer.objects.filter(
        Q(first_name__icontains=post_data['first_name']) &
        Q(last_name__icontains=post_data['last_name']) &
        Q(doctor=post_data['doctor'])
    )

当我没有在表单的选定字段中选择医生时,这将不起作用。如果我删除

Q(doctor-post_data['doctor']

搜索按预期工作。如果我保持原样并从表单的选择字段中选择医生,那么它可以工作,但不是我想要的。为什么添加医生中断功能?

The form is:

class CustomerSearchForm(Form):
    #form fields
    doctor = forms.ModelChoiceField (required=False, queryset=Doctor.objects.all(), widget=Select(attrs={"class":"form-control input-sm"}))

有什么问题?

4

1 回答 1

1

您可以Q有条件地编写表达式:

qexpr = ( Q(first_name__icontains=post_data['first_name']) &
          Q(last_name__icontains=post_data['last_name']) )
if post_data['doctor']:
    qexpr &= Q(doctor=post_data['doctor'])
customers = Customer.objects.filter(qexpr)

如果在表单的输入中未选择任何内容,则无条件过滤器doctor=post_data['doctor']将评估为,然后将转换为生成的 SQL 查询中的任何一个(不确定 Django 的 ORM 将如何处理它,我还没有测试过),两者都没有其中将匹配模型中的任何记录。doctor=Nonedoctordoctor_id = NULLdoctor_id IS NULL

于 2014-02-03T08:32:21.890 回答