Question

I have a model like this

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

I wanted to create a search customer form, so I created a new form (not a ModelForm, cause I only wanted the fields of the form not the save method) , which has fields of the customer. The functionality I want to achieve is:

  • If the form is empty and user presses search show all customers
  • If the form has fields with data do an AND Search with fields

The search fields I have implemented for test puproses are the following first_name, last_name and doctor. I used Q objects like this:

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'])
    )

which won't work when I haven't chosen doctor in the form's selected field. If I remove

Q(doctor-post_data['doctor']

the search works as expected. If I leave it as is and do choose a doctor from form's selecte field then it works but its not what I want. Why does the add of doctor break functionality?

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

What can be wrong?

Was it helpful?

Solution

You can compose your Q expressions conditionally:

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)

The unconditional filter on doctor=post_data['doctor'] would evaluate to doctor=None if nothing is selected in the doctor input of your form, which will then translate to either doctor_id = NULL or to doctor_id IS NULL in the generated SQL query (not certain how Django's ORM would handle it, and I haven't tested), neither of which will match any records in your model.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top