【问题标题】:django q objects and more advanced searchdjango q 对象和更高级的搜索
【发布时间】:2014-02-26 15:49:50
【问题描述】:

我有一个这样的模型

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

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

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

我为测试目的实现的搜索字段是以下名字、姓氏和医生。我使用了这样的 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"}))

有什么问题?

【问题讨论】:

    标签: django forms django-queryset django-q


    【解决方案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 输入中未选择任何内容,doctor=post_data['doctor'] 上的无条件过滤器将评估为 doctor=None,然后在生成的 SQL 查询中转换为 doctor_id = NULLdoctor_id IS NULL (不确定 Django 的 ORM 会如何处理它,我还没有测试过),它们都不会匹配你模型中的任何记录。

    【讨论】:

      猜你喜欢
      • 2015-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      • 2018-04-03
      • 2011-04-18
      • 2021-08-30
      • 2015-06-23
      相关资源
      最近更新 更多