How can I use Q objects on Two Dynamic Search Forms in Django

Issue

I am working on a Django project where I want to search profile records for those that are resident in a particular country and state.

In this project I would be collecting data of people from different countries and their respective states, so I want a situation where I can have two Search Forms for Country and State.

The form should be able to allow me select list of countries in the Profile Model while the state form should be able to allow me type and search for a state in the selected country.

The result should be a list of persons in the selected Country and searched state.Please understand that I decided to go with Q objects because I learn that it makes queries efficient.

Here are my model code:

class Profile(models.Model):
    applicant = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
    surname = models.CharField(max_length=10, null=True)
    othernames = models.CharField(max_length=30, null=True)
    gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
    nation = models.CharField(max_length=10, choices=NATION, blank=True, null=True)
    state = models.CharField(max_length=20, null=True)
    address = models.CharField(max_length=200, null=True)
    phone = models.CharField(max_length=11, null=True)
    image = models.ImageField(default='avatar.jpg', upload_to ='profile_images')

Here is my search form code:

class Applicant_Search_Form(forms.ModelForm):

class Meta:
    model = Profile
    fields = ['nation', 'state']

Here is my views code:

def SearchApplicants(request):

form = Applicant_Search_Form(request.GET or None)

if form:
    list_submited = Q(nation__icontains = form['nation'].value()) & Q(state__icontains = form['state'].value())

else:
    list_submited = Profile.objects.all()

paginator = Paginator(list_submited, 5)
page = request.GET.get('page')
paged_listApps = paginator.get_page(page)

context = {
'list_applicants':paged_listApps,
'form':form,


}

return render(request, 'user/list_applicants.html',context)

I have tried running the above code but I am have a TypeError which says ‘Q’ object is not subscriptable.

Someone should kindly help with how to solve this problem and possibly the best approach to this kind of search.Thank in anticipation to your answers.

Solution

You should filter the Profile.objects.all() queryset, so:

def SearchApplicants(request):
    form = Applicant_Search_Form(request.GET)
    if form.is_valid():
        list_submited = Profile.objects.filter(
            nation__icontains=form.cleaned_data['nation'],
            state__icontains=form.cleaned_data['state']
        )
    else:
        list_submited = Profile.objects.all()
    # …

Note: Functions are normally written in snake_case, not PascalCase, therefore it is
advisable to rename your function to search_applicants, not SearchApplicants.


Note: Forms in Django are written in PascalCase, not snake_case,
so you might want to rename the model from Applicant_Search_Form to ApplicantSearchForm.

Answered By – Willem Van Onsem

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published