Mastering Search in Django REST: A Guide to Vector Queries and Rank

Django REST Framework (DRF) allows you to build powerful APIs quickly. Integrating search functionality into your DRF project using PostgreSQL’s full-text search capabilities can enhance your application’s usability. In this blog, we’ll adapt our previous Django example to use DRF, implementing basic and advanced search using SearchVector, SearchQuery, and SearchRank.

Prerequisites

Before diving into the implementation, ensure you have the following prerequisites:

  1. Basic Understanding of Django and Django REST Framework: Familiarity with Django models, views, and serializers is essential. You should know how to create a simple Django project and app, as well as basic REST API principles.
  2. PostgreSQL Database: Django’s full-text search capabilities require PostgreSQL. Ensure you have PostgreSQL installed and running on your machine.
  3. Python Environment: Have a working Python environment set up. It’s recommended to use a virtual environment for your Django projects.
  4. Django and Django REST Framework Installed: If you haven’t installed them yet, you can do so with:
pip install django djangorestframework psycopg2

Related read: Building Powerful REST APIs with Node.js, Prisma ORM, and PostgreSQL

Setting Up Your Django Project

1. Install PostgreSQL: Ensure you’re using PostgreSQL, as Django’s full-text search capabilities leverage its built-in features.

2. Install Required Packages: Ensure your Django project has the necessary dependencies.

pip install django psycopg2

3. Create a Model: Suppose you have a simple Article model for this example.

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

4. Set Up the Database: Configure your settings.py to connect to PostgreSQL.

Ready to Enhance Your Django API? Start Integrating Powerful Search Functionality Today!

Implementing Search in Django REST Framework

Step 1: Creating Serializers

Create a serializer for the Article model in serializers.py.

from rest_framework import serializers
from .models import Article

class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = '__all__'

Step 2: Basic Search Using Contains

First, implement a basic search using Django’s contains filter, allowing case-insensitive substring matching.

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Article
from .serializers import ArticleSerializer

class BasicSearchView(APIView):
    def get(self, request):
        query = request.query_params.get('q', None)
        if query:
           articles = Article.objects.filter(title__icontains=query)
        else:
           articles = Article.objects.all()

        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)

Step 3: Advanced Search Using PostgreSQL Full-Text Search

Next, we’ll enhance our search functionality using SearchVector, SearchQuery, and SearchRank.

from django.contrib.postgres.search import SearchVector, SearchQuery, SearchRank

class AdvancedSearchView(APIView):
    def get(self, request):
        query = request.query_params.get('q', None)
        if query:
            search_vector = SearchVector('title', 'content')
            search_query = SearchQuery(query)
            articles = Article.objects.annotate(
                rank=SearchRank(search_vector, search_query)
            ).filter(rank__gte=0.3).order_by('-rank') # Adjust threshold as necessary
        else:
            articles = Article.objects.all()

        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)

Step 4: Setting Up URLs

Define the URLs for your search views in urls.py.

from django.urls import path
from .views import BasicSearchView, AdvancedSearchView

urlpatterns = [
    path('search/basic/', BasicSearchView.as_view(), name='basic-search'),
    path('search/advanced/', AdvancedSearchView.as_view(), name='advanced-search'),
]

Step 5: Testing the API

You can now test the API endpoints using tools like Postman or curl.

Basic Search Example

To perform a basic search for articles, make a GET request to /search/basic/?q=django.

GET /search/basic/?q=django

Advanced Search Example

To perform an advanced search, make a GET request to /search/advanced/?q=django.

GET /search/advanced/?q=django

Example Response

For both searches, you might get a response like this:

[
   {
       "id": 1,
       "title": "Understanding Django",
       "content": "Django is a powerful web framework...",
       "created_at": "2023-09-23T12:00:00Z"
   },
   ...
]
coma

Conclusion

By following these steps, you have successfully implemented both basic and advanced search functionality in a Django REST Framework application. The basic search uses Django’s contains, while the advanced search leverages PostgreSQL’s full-text search capabilities.

Feel free to expand this implementation by adding features such as pagination, filtering, or integrating a frontend to display search results dynamically. Happy coding!

Keep Reading

Keep Reading

  • Service
  • Career
  • Let's create something together!

  • We’re looking for the best. Are you in?