Meilisearch indexer for django models and related utilities
Project description
✨ Django Meilisearch Indexer ✨
Provides a MeilisearchModelIndexer
class to easily index django models in Meilisearch.
💻 How to install
The package is available on PyPi with the name django_meilisearch_indexer
.
Simply run:
pip install django_meilisearch_indexer
⚡ Quick start
Here's a basic example:
# Imports
from typing import Any, Dict
from django.db import models
from django_meilisearch_indexer import MeilisearchModelIndexer
# Model
class Tag(models.Model):
name = models.CharField(max_length=100, unique=True)
color = models.CharField(max_length=100)
is_disabled = models.BooleanField(default=False)
# Indexer
class TagIndexer(MeilisearchModelIndexer[Tag]):
MODEL_CLASS = Tag
PRIMARY_KEY = "id"
SETTINGS = {
"filterableAttributes": ["is_disabled"],
"searchableAttributes": ["name"],
"sortableAttributes": ["name", "color"],
}
@classmethod
def build_object(cls, instance: Tag) -> Dict[str, Any]:
return {
"id": instance.id,
"name": instance.name,
"color": instance.color,
"is_disabled": instance.is_disabled,
}
@classmethod
def index_name(cls) -> str:
return "tags"
# Call
TagIndexer.maybe_create_index()
📕 Available modules
This library contains the following importable modules:
# The main indexer
MeilisearchModelIndexer
# Some serializers for your API
MeilisearchOnlyHitsResponseSerializer
MeilisearchSearchResultsSerializer
MeilisearchSimpleSearchSerializer
# Lots of typing classes
Faceting
MeilisearchFilters
MeilisearchFilterValue
MeilisearchSearchHits
MeilisearchSearchParameters
MeilisearchSearchResults
MeilisearchSettings
MinWordSizeForTypos
Pagination
Precision
RankingRule
TypoTolerance
🍜 Recipes
Create indexes on boot
Generate your indexes on boot using AppConfig.ready()
.
class TagConfig(AppConfig):
name = "tags"
def ready(self) -> None:
from django.conf import settings
from tags.indexers import TagIndexer
if settings.IS_RUNNING_MYPY or settings.ENVIRONMENT == "test":
return
TagIndexer.maybe_create_index()
Async actions with celery
Make your indexation asynchronous using celery
and rabbitmq
.
from typing import Dict, List
from celery import shared_task
from django.conf import settings
from django.db.models import Q
@shared_task(queue=settings.RABBITMQ_USER_QUEUE)
def index_tags(ids: List[int]) -> Dict[str, str]:
from tags.indexers import TagIndexer
TagIndexer.index_from_query(Q(pk__in=ids))
return {"result": "ok"}
# ...
index_tags.s(ids).apply_async(countdown=5)
Mock for testing
For testing, you'll need to mock the following tasks:
from unittest import TestCase
from unittest.mock import patch
class TagTestCase(TestCase):
def setUp(self) -> None:
super().setUp()
self._mock_indexers()
self._mock_celery_tasks()
def _mock_indexers(self) -> None:
"""
Patches the `index_name` functions of all indexers.
This allows running tests against a Meilisearch server
without overwriting the actual index.
"""
self.indexer_mocks = [
patch(
"tags.indexers.TagIndexer.index_name",
return_value="test_tags",
).start(),
]
# If you are using celery tasks
def _mock_celery_tasks(self) -> None:
"""Patches the celery tasks in both forms: `delay` and `apply_async`."""
names = [
"tags.tasks.index_tags.delay",
"tags.tasks.index_tags.apply_async",
]
self.celery_task_mocks = {name: patch(name).start() for name in names}
def test_something(self):
# ...
self.celery_task_mocks[
"tags.tasks.index_tags.apply_async"
].assert_called_once_with(([recipe.id],), {}, countdown=5)
# ...
Admin actions
To trigger your indexations through the django admin interface, you can add a custom action like so:
from django.contrib import admin
from django.db.models import QuerySet
from django.http import HttpRequest, HttpResponseRedirect
from tags import tasks
from tags.models import Tag
@admin.action(description="[Meilisearch] Index selected item(s)")
def index_multiple(
model_admin: admin.ModelAdmin,
request: HttpRequest,
queryset: QuerySet,
) -> HttpResponseRedirect:
ids = list(queryset.values_list("id", flat=True))
model_admin.index_task.s(ids).apply_async(countdown=5)
model_admin.message_user(request, f"Indexing {len(ids)} items(s) on Meilisearch")
return HttpResponseRedirect(request.get_full_path())
class TagAdmin(admin.ModelAdmin):
index_task = tasks.index_tags
extra_actions = [index_multiple]
# ...
🔗 Useful links
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django_meilisearch_indexer-1.0.0.tar.gz
.
File metadata
- Download URL: django_meilisearch_indexer-1.0.0.tar.gz
- Upload date:
- Size: 11.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d675b86a185e0cfc2f6cb87b20ff6475eab1eff0d60683ae9654c8c0350291ae |
|
MD5 | ab9610e8e6b0723dfef92da1f934bf91 |
|
BLAKE2b-256 | 81eeee6aafabbb66564a18d207aec8987708843147e5735605041a453200da63 |
File details
Details for the file django_meilisearch_indexer-1.0.0-py3-none-any.whl
.
File metadata
- Download URL: django_meilisearch_indexer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 10.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | fa7e55a6d6bb10326387f23e21fb2560afc94db486732f623ae75a3bdf458e31 |
|
MD5 | 0f3a6a21cb4d7c61df853bbef09854a7 |
|
BLAKE2b-256 | 8dfd0f33d62aae3796021f0cb5f7c4b600c448673ac879e18d1607b72fbda00a |