Skip to content

Commit d1dab58

Browse files
authored
PostgreSQL full-text search in the Django Admin
1 parent 42f5279 commit d1dab58

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# PostgreSQL full-text search in the Django Admin
2+
3+
Django 3.1 introduces PostgreSQL `search_type="websearch"` - which gives you search with advanced operators like `"phrase search" -excluding`. James Turk [wrote about this here](https://jamesturk.net/posts/websearch-in-django-31/), and it's also in [my weeknotes](https://simonwillison.net/2020/Jul/23/datasette-copyable-datasette-insert-api/).
4+
5+
I decided to add it to my Django Admin interface. It was _really easy_ using the `get_search_results()` model admin method, [documented here](https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_search_results).
6+
7+
My models already have a `search_document` full-text search column, as described in [Implementing faceted search with Django and PostgreSQL](https://simonwillison.net/2017/Oct/5/django-postgresql-faceted-search/). So all I needed to add to my `ModelAdmin` subclasses was this:
8+
9+
```python
10+
def get_search_results(self, request, queryset, search_term):
11+
if not search_term:
12+
return super().get_search_results(
13+
request, queryset, search_term
14+
)
15+
query = SearchQuery(search_term, search_type="websearch")
16+
rank = SearchRank(F("search_document"), query)
17+
queryset = (
18+
queryset
19+
.annotate(rank=rank)
20+
.filter(search_document=query)
21+
.order_by("-rank")
22+
)
23+
return queryset, False
24+
```
25+
Here's [the full implementation](https://github.com/simonw/simonwillisonblog/blob/6c0de9f9976ef831fe92106be662d77dfe80b32a/blog/admin.py) for my personal blog.

0 commit comments

Comments
 (0)