initail elasticsearch

This commit is contained in:
2025-05-06 16:22:35 +03:30
parent ec58d9ef5e
commit 3dce7fc344
18 changed files with 176 additions and 11 deletions

View File

@@ -4,6 +4,7 @@ from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
from apps.authentication.models import User
from rest_framework.views import APIView
from django.db import transaction
@@ -28,3 +29,7 @@ class Authentication(ModelViewSet):
@transaction.atomic
def login(self, request):
pass
class UserViewSet(ModelViewSet):
pass

View File

@@ -0,0 +1,53 @@
from apps.authentication.api.v1.serializers.serializer import UserSerializer
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.viewsets import ModelViewSet, ViewSet
from apps.authentication.documents import UserDocument
from rest_framework.response import Response
from django.http.response import HttpResponse
from apps.authentication.models import User
from rest_framework.views import APIView
from elasticsearch_dsl.query import Q
import abc
class PaginatedElasticSearchApiView(APIView, LimitOffsetPagination):
"""Base ApiView Class for elasticsearch views with pagination
Other ApiView classes should inherit from this class"""
serializer_class = None
document_class = None
@abc.abstractmethod
def generate_q_expression(self, query):
"""This method should be overridden
and return a Q() expression."""
def get(self, request, query):
try:
q = self.generate_q_expression(query)
search = self.document_class.search().query(q)
response = search.execute()
print(f"Found {response.hits.total.value} hit(s) for query: '{query}'")
results = self.paginate_queryset(response, request, view=self) # noqa
serializer = self.serializer_class(results, many=True)
return self.get_paginated_response(serializer.data)
except Exception as e:
return HttpResponse(e, status=500)
class SearchUsersApiView(PaginatedElasticSearchApiView): # noqa
"""Search in Users"""
serializer_class = UserSerializer
document_class = UserDocument
def generate_q_expression(self, query):
return Q(
'multi_match',
query=query,
fields=[
'username',
'mobile'
], fuzziness='auto'
)

View File

@@ -0,0 +1,11 @@
from rest_framework import serializers
from apps.authentication.models import User
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
'username',
'mobile'
]

View File

@@ -5,10 +5,14 @@ from rest_framework_simplejwt.views import (
TokenRefreshView,
TokenVerifyView
)
from .api import CustomizedTokenObtainPairView
from .api import (
CustomizedTokenObtainPairView
)
from .search_view import SearchUsersApiView
urlpatterns = [
path('login/', CustomizedTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('search_user/<str:query>', SearchUsersApiView.as_view(), name='search_user'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('token/verify/', TokenVerifyView.as_view(), name='token_verify'),
]

View File

@@ -0,0 +1,24 @@
from .models import User, Province
from django_elasticsearch_dsl import Document, fields
from django_elasticsearch_dsl.registries import registry
@registry.register_document
class UserDocument(Document):
"""ElasticSearch Document for indexing users"""
class Index:
name = 'users'
settings = {
'number_of_shards': 1,
'number_of_replicas': 0 # number of copies from data in document
}
class Django:
model = User
fields = [
"id",
"username",
"mobile",
"nationality"
]

View File

@@ -1,3 +1 @@
from django.shortcuts import render
# Create your views here.

0
apps/search/__init__.py Normal file
View File

3
apps/search/admin.py Normal file
View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
apps/search/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class SearchConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.search'

BIN
apps/search/certs/http.p12 Normal file

Binary file not shown.

View File

@@ -0,0 +1,31 @@
-----BEGIN CERTIFICATE-----
MIIFWjCCA0KgAwIBAgIVAJzJVclRzLeDn2zXiqaZcs009WrZMA0GCSqGSIb3DQEB
CwUAMDwxOjA4BgNVBAMTMUVsYXN0aWNzZWFyY2ggc2VjdXJpdHkgYXV0by1jb25m
aWd1cmF0aW9uIEhUVFAgQ0EwHhcNMjUwNTA2MDUyODMwWhcNMjgwNTA1MDUyODMw
WjA8MTowOAYDVQQDEzFFbGFzdGljc2VhcmNoIHNlY3VyaXR5IGF1dG8tY29uZmln
dXJhdGlvbiBIVFRQIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
lpZfJN3SR/HhgRd6wDOEZwSanoSgI0s/y7RcLBxtH29HGmlgegX38KugErYhBOx0
CgGivcUG7CiyWPEg8CP71+pn1iQburH1zcnKovLO5pZc7p2bnnKESNsAH9j+EEza
NVUR9+tFyKaoss8QU0r1uKHFjghWR8aFRBVjPIPZs8z2GqbRzI0NBHmhxD0Tedp/
67amF7N/64ID1LVgUWyQH28DtguEjp4jEL3gbU7gEiorg42XHymu4sKieWJQczaH
sVDTmcT8HhY8wL7qf9KD6UPyqtT2NnxyODWnaO2epjbII0XvIrXH3mfPzxNQ2mQT
2V+sv34dHS6yCr+jHGU2Z6nD+5Kr2l8QRJaxW0WNHgcKXW45TLbEWDOxfJCGSQYU
zXP9LsLk2SBeAQ4OECs0jBymVSf4c4TaYtloVpdZTKMbm66VwfsJjSxSKd03HTWz
SESkM0YQ8y33SU+RDkVCkWlV3isf1/FzibfSeDbPlrRIfV0oRlzkiY4mLrytQO2Q
L7JDZtZ2+y04AgtzrAtHwfAH/KsKjUr63gzouIwfdahZudQvNYQUCSyOMLGGQ5VJ
UA8K5cCj+Z0C0R7/A/0uNsMhIRA2KftFJtfEnQok3m7kJnrrkD8xUaJ3P8FGdP9J
fIy6JXKBp1nBS+YAkou6tR7BsPTrroKDyK4pbhCsrt8CAwEAAaNTMFEwHQYDVR0O
BBYEFHEPMqbc3BiLqvXgYaxm2yqMQp1MMB8GA1UdIwQYMBaAFHEPMqbc3BiLqvXg
Yaxm2yqMQp1MMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBADB6
te9AWGobEXYfEt+0rlsTWJNVksyQs94OTfBLtjgPcDb0EzXteoxrFSUh4KblioT3
+KVGPNfgYEEH6hnPNU2ea2ZL3cVDdrSWwCYqSJAmxOKKPpISu2/HZ2xtVuEjWqSe
CJcJvb2Fh8HSSRFTwko3h8B9ie4cb3cOiHle6tM+Kc1JxxLvAurlHl0xq4wdZJqW
RJUMYs+R+gCQiT4wBZlFoUHSCOlSDPb0YxMDvISaJ4DOxGjbL2TSw6wP9LtOcUlA
Agjgsq+xzCim2vzW3h7IMdw1z/amXbyl1J3an7n8P41deB/7EePiJuNVU9zsSu68
anlQamvPawEFsucL3QfiX0kSQd1pcT1r/XYAm0jPVBx2Qc3EOoD4wlkz5ATpE1ts
vWCgfvQsuhUoL6cD9WFzAiWXXZ3qRDcY5L7zs0c/geUybRB/gWgMh/ROypfUoxfT
F0Cy/cfm/cBpbdy7frN9XWAigh/TDnCdwnOhfcvwr3AMxVR7X7NIVwBvTOPGIfwh
FLoPiaPrGkPntItdZWqGUUpkPrIzOpSZWurJ40pPCc0uBVUudYMH686MiyB5wZSS
/sGJIjfeivKVvH77kKCXld3Z35/E47msUvtl/DuUVtXQb12tQ4boyQJ6O6JVyK2n
1cRq9qLHcpfoG81BzrGIJvTWOBXTs02lOCRObF7z
-----END CERTIFICATE-----

Binary file not shown.

3
apps/search/models.py Normal file
View File

@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

3
apps/search/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

4
apps/search/views.py Normal file
View File

@@ -0,0 +1,4 @@
from django.shortcuts import render
from elasticsearch_dsl import Q
from apps.authentication.models import User
from apps.authentication.documents import UserDocument

View File

@@ -13,6 +13,12 @@ class Tag(BaseModel):
related_name="tag_province",
null=True
)
city = models.ForeignKey(
auth_models.City,
on_delete=models.CASCADE,
related_name='tag_city',
null=True
)
organization = models.ForeignKey(
auth_models.Organization,
on_delete=models.CASCADE,