Set search fields using the query parameter

Akshar Raaj
Jul 17 · 4 min read
Dynamic search fields in DRF

The Django REST framework provides search functionality out of the box.

Search can be accomplished by following three steps:

  • Setting search_fields in the class
  • Setting filter_backends in the class
  • Sending search query parameter in the request

search specifies the pattern that needs to be matched. search_fields specify the database columns against which the pattern needs to be matched.

DRF default behavior works with static search_fields.

In this piece, we discuss the limitations of static search_fields and how to make search_fields dynamic.


Usefulness

Dynamic searching ability in the back end will allow users to perform more granular searches.

This will come in handy in a scenario where your front end lists all the fields/columns of the model and allows users to select the fields against which the pattern should be matched.

Users will also have the ability to choose the matching type. Users can choose LIKE matching, exact matching, or starts with matching.


Setup

We will use the following models in this post:


Static Search

Let’s first apply search on static fields, and then we will make the search fields dynamic.

Let’s add the view, serializer, and URL pattern.

With this, we should be able to get all the questions. The search functionality isn’t added yet.

Try sending a pattern, say Samsung, as a search query parameter. search query parameter doesn’t have any effect on the returned response. Questions without the pattern Samsung are also returned in the response.

Let’s add search functionality to the view.

When we send a pattern in a GET query parameter, we want the term to be matched against the question_text column. We need to add search_fields and filter_backends to achieve this.

Let’s make the request again. We’ll only get questions that have Samsung in their question_text.

This question is authored by charles.

Let’s send charles as a search pattern in a GET request and see if we get the same response.

We did not get the expected question in response because we haven’t configured our view to match the pattern against the author column.

We can achieve that by adding author to search_fields.

search_fields = ['question_text', 'author']

Issues With This Approach

We have added question_text, as well as author, to search_fields.

We want to search for questions authored by charles. Assume that there is a question authored by tolkien with the text: "Do you love charles novels?

In such cases, when we search for the pattern charles, even this question would come up despite it not being written by charles.

This question came up because the term charles appears in the question_text.


Better Approach

A better approach would be allowing end users to specify the fields on which they want the pattern to be matched. We essentially want to make fields dynamic.

We need to create a custom filter back end to achieve this. This back end would extend from DRF SearchFilter and would override the method get_search_fields().

Let’s set this filter back end as filter_backends of view and remove static search_fields from the view.

We can now make a request with the pattern as charles and search_fields as author.

We are using Django’s getlist(). This enables us to specify multiple fields as search_fields query parameters.

Now, we want charles to be looked up in both author and question_text columns. Let’s send question_text as well as author in the search_fields query parameter.

Thanks for reading!

You can read my next post, which talks about extracting more out of DRF serializers.

Better Programming

Advice for programmers.

Akshar Raaj

Written by

Engineer | Open Source | Blogger | Speaker. My posts have been read over a million times. https://www.agiliq.com/authors/#Akshar https://bit.ly/2TaRqji

Better Programming

Advice for programmers.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade