Skip to content

Commit c3307c9

Browse files
committed
configure postgresql search system
1 parent 1ceccb5 commit c3307c9

File tree

6 files changed

+554
-10
lines changed

6 files changed

+554
-10
lines changed

apps/blog/filters.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import django_filters
2+
3+
from .models import Post
4+
5+
6+
class PostFilter(django_filters.FilterSet):
7+
title = django_filters.CharFilter(lookup_expr="icontains")
8+
description = django_filters.CharFilter(lookup_expr="icontains")
9+
content = django_filters.CharFilter(lookup_expr="icontains")
10+
created_at = django_filters.DateFromToRangeFilter()
11+
12+
class Meta:
13+
model = Post
14+
fields = ['title', 'description', 'content', 'created_at']

apps/blog/utils.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
11
from django.db.models import QuerySet
22
from django.db.models import Q
3-
from django.core.paginator import Paginator, Page, EmptyPage, PageNotAnInteger
3+
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
4+
from django.core.paginator import Paginator, Page, EmptyPage, PageNotAnInteger, InvalidPage
5+
from django.conf import settings
46

57
from .models import PostLike, PostDislike, Post, PostComment
68

79

810
def get_search_model_queryset(
9-
model_queryset: QuerySet, search_query: str = None
11+
model_queryset: QuerySet, query: str = None
1012
) -> QuerySet:
11-
if not search_query:
13+
if not query:
1214
return model_queryset
1315

14-
search_query = model_queryset.filter(
15-
Q(title__icontains=search_query)
16-
| Q(description__icontains=search_query)
17-
| Q(content__icontains=search_query)
18-
)
16+
search_vector = SearchVector("title", "description", "content")
17+
search_query = SearchQuery(query)
1918

20-
return search_query
19+
if settings.DATABASES['default']['ENGINE'] == 'django.db.backends.postgresql':
20+
# PostgreSQL search
21+
queryset = model_queryset.annotate(
22+
search=search_vector,
23+
rank=SearchRank(search_vector, search_query),
24+
).filter(search=search_query).order_by('-rank')
25+
else:
26+
# SQLite3 search
27+
queryset = model_queryset.filter(
28+
Q(title__icontains=query)
29+
| Q(description__icontains=query)
30+
| Q(content__icontains=query)
31+
)
32+
33+
return queryset
2134

2235

2336
def get_pagination_obj(model_queryset: QuerySet, page: int = 1, size: int = 4) -> Page:
@@ -29,6 +42,9 @@ def get_pagination_obj(model_queryset: QuerySet, page: int = 1, size: int = 4) -
2942
except PageNotAnInteger:
3043
page_obj = paginator.page(1)
3144

45+
except InvalidPage:
46+
page_obj = paginator.page(1)
47+
3248
except EmptyPage:
3349
page_obj = paginator.page(paginator.num_pages)
3450

apps/users/api_endpoints/users/User/tests.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,6 @@ def _create_user():
102102
_check_user_error_field()
103103
_check_user_passwords_field()
104104
_create_user()
105+
106+
def test_api_user_update(self):
107+
pass
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
from rest_framework.test import APITestCase
2+
from rest_framework_simplejwt.tokens import RefreshToken
3+
from apps.users.models import UserProfile, User
4+
5+
6+
class UserProfileApiTestCase(APITestCase):
7+
def setUp(self) -> None:
8+
self.username = "Admin"
9+
self.email = "admin@gmail.com"
10+
self.password = "password"
11+
user = User.objects.create(
12+
username=self.username,
13+
email=self.email,
14+
)
15+
user.set_password(self.password)
16+
user.save()
17+
self.user = user
18+
refresh = RefreshToken.for_user(self.user)
19+
self.token = str(refresh.access_token)
20+
return super().setUp()
21+
22+

0 commit comments

Comments
 (0)