implement simple backend search for items and tickets
This commit is contained in:
parent
f2647f0dbd
commit
fdf5ab8ad1
6 changed files with 160 additions and 9 deletions
|
@ -15,7 +15,7 @@ from mail.models import Email
|
|||
from mail.protocol import send_smtp, make_reply, collect_references
|
||||
from notify_sessions.models import SystemEvent
|
||||
from tickets.models import IssueThread, Comment, STATE_CHOICES, ShippingVoucher, ItemRelation
|
||||
from tickets.serializers import IssueSerializer, CommentSerializer, ShippingVoucherSerializer
|
||||
from tickets.serializers import IssueSerializer, CommentSerializer, ShippingVoucherSerializer, SearchResultSerializer
|
||||
from tickets.shared_serializers import RelationSerializer
|
||||
|
||||
|
||||
|
@ -136,6 +136,30 @@ def add_comment(request, pk):
|
|||
return Response(CommentSerializer(comment).data, status=status.HTTP_201_CREATED)
|
||||
|
||||
|
||||
def filter_issues(issues, query):
|
||||
query_tokens = query.split(' ')
|
||||
for issue in issues:
|
||||
value = 0
|
||||
for token in query_tokens:
|
||||
if token in issue.description:
|
||||
value += 1
|
||||
if value > 0:
|
||||
yield {'search_score': value, 'issue': issue}
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([])
|
||||
# @permission_classes([IsAuthenticated])
|
||||
# @permission_required('view_item', raise_exception=True)
|
||||
def search_issues(request, event_slug, query):
|
||||
try:
|
||||
event = Event.objects.get(slug=event_slug)
|
||||
items = filter_issues(IssueThread.objects.filter(event=event), b64decode(query).decode('utf-8'))
|
||||
return Response(SearchResultSerializer(items, many=True).data)
|
||||
except Event.DoesNotExist:
|
||||
return Response(status=404)
|
||||
|
||||
|
||||
router = routers.SimpleRouter()
|
||||
router.register(r'tickets', IssueViewSet, basename='issues')
|
||||
router.register(r'matches', RelationViewSet, basename='matches')
|
||||
|
@ -146,4 +170,6 @@ urlpatterns = ([
|
|||
re_path(r'^tickets/(?P<pk>\d+)/reply/$', reply, name='reply'),
|
||||
re_path(r'^tickets/(?P<pk>\d+)/comment/$', add_comment, name='add_comment'),
|
||||
re_path(r'^(?P<event_slug>[\w-]+)/tickets/manual/$', manual_ticket, name='manual_ticket'),
|
||||
re_path(r'^(?P<event_slug>[\w-]+)/tickets/(?P<query>[-A-Za-z0-9+/]*={0,3})/$', search_issues,
|
||||
name='search_issues'),
|
||||
] + router.urls)
|
||||
|
|
|
@ -130,3 +130,14 @@ class IssueSerializer(BasicIssueSerializer):
|
|||
})
|
||||
return sorted(timeline, key=lambda x: x['timestamp'])
|
||||
|
||||
|
||||
|
||||
class SearchResultSerializer(serializers.Serializer):
|
||||
search_score = serializers.IntegerField()
|
||||
item = IssueSerializer()
|
||||
|
||||
def to_representation(self, instance):
|
||||
return {**IssueSerializer(instance['item']).data, 'search_score': instance['search_score']}
|
||||
|
||||
class Meta:
|
||||
model = IssueThread
|
||||
|
|
|
@ -9,6 +9,8 @@ from tickets.models import IssueThread, StateChange, Comment, ItemRelation
|
|||
from django.contrib.auth.models import Permission
|
||||
from knox.models import AuthToken
|
||||
|
||||
from base64 import b64encode
|
||||
|
||||
|
||||
class IssueApiTest(TestCase):
|
||||
|
||||
|
@ -365,3 +367,21 @@ class IssueApiTest(TestCase):
|
|||
self.assertEqual('pending_new', timeline[0]['state'])
|
||||
self.assertEqual('assignment', timeline[1]['type'])
|
||||
self.assertEqual(self.user.username, timeline[1]['assigned_to'])
|
||||
|
||||
|
||||
class IssueSearchTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.event = Event.objects.create(slug='EVENT', name='Event')
|
||||
self.user = ExtendedUser.objects.create_user('testuser', 'test', 'test')
|
||||
self.user.user_permissions.add(*Permission.objects.all())
|
||||
self.user.save()
|
||||
self.token = AuthToken.objects.create(user=self.user)
|
||||
self.client = Client(headers={'Authorization': 'Token ' + self.token[1]})
|
||||
|
||||
def test_search(self):
|
||||
search_query = b64encode(b'abc').decode('utf-8')
|
||||
response = self.client.get(f'/api/2/{self.event.slug}/tickets/{search_query}/')
|
||||
self.assertEqual(200, response.status_code)
|
||||
self.assertEqual([], response.json())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue