Update dynamic_search app API to support document page searches.

This commit is contained in:
Roberto Rosario
2016-10-28 02:44:02 -04:00
parent 2ad40a0970
commit c10637aaa4
6 changed files with 117 additions and 25 deletions

View File

@@ -1,28 +1,49 @@
from __future__ import unicode_literals
from django.http import Http404, HttpResponseRedirect
from rest_framework import generics
from rest_framework.exceptions import ParseError
from rest_api.filters import MayanObjectPermissionsFilter
from .classes import SearchModel
from .mixins import SearchModelMixin
class APISearchView(generics.ListAPIView):
class APISearchView(SearchModelMixin, generics.ListAPIView):
"""
Perform a search operaton
q -- Term that will be used for the search.
Perform a search operation
---
GET:
omit_serializer: true
parameters:
- name: search_model
paramType: path
type: string
required: true
description: Possible values are "documents.Document" or "document.DocumentPageResult"
- name: q
paramType: query
type: string
description: Term that will be used for the search.
"""
filter_backends = (MayanObjectPermissionsFilter,)
def get_queryset(self):
search_class = self.get_search_class()
if search_class.permission:
self.mayan_object_permissions = {'GET': (search_class.permission,)}
search_model = self.get_search_model()
# Override serializer class just before producing the queryset of
# search results
self.serializer_class = search_model.serializer
if search_model.permission:
self.mayan_object_permissions = {'GET': (search_model.permission,)}
try:
queryset, ids, timedelta = search_class.search(
queryset, ids, timedelta = search_model.search(
query_string=self.request.GET, user=self.request.user
)
except Exception as exception:
@@ -30,8 +51,50 @@ class APISearchView(generics.ListAPIView):
return queryset
def get_search_class(self):
return SearchModel.get('documents.Document')
def get_serializer_class(self):
return self.get_search_class().serializer
class APIAdvancedSearchView(SearchModelMixin, generics.ListAPIView):
"""
Perform an advanced search operation
---
GET:
omit_serializer: true
parameters:
- name: search_model
paramType: path
type: string
required: true
description: Possible values are "documents.Document" or "document.DocumentPageResult"
- name: _match_all
paramType: query
type: string
description: When checked, only results that match all fields will be returned. When unchecked results that match at least one field will be returned. Possible values are "on" or "off"
"""
filter_backends = (MayanObjectPermissionsFilter,)
def get_queryset(self):
self.search_model = self.get_search_model()
# Override serializer class just before producing the queryset of
# search results
self.serializer_class = self.search_model.serializer
if self.search_model.permission:
self.mayan_object_permissions = {
'GET': (self.search_model.permission,)
}
if self.request.GET.get('_match_all', 'off') == 'on':
global_and_search=True
else:
global_and_search=False
try:
queryset, ids, timedelta = self.search_model.search(
query_string=self.request.GET, user=self.request.user,
global_and_search=global_and_search
)
except Exception as exception:
raise ParseError(unicode(exception))
return queryset

View File

@@ -8,6 +8,7 @@ from django.apps import apps
from django.core.exceptions import PermissionDenied
from django.db.models import Q
from django.utils.module_loading import import_string
from django.utils.translation import ugettext as _
from acls.models import AccessControlList
from permissions import Permission
@@ -22,12 +23,23 @@ class SearchModel(object):
@classmethod
def get(cls, full_name):
result = cls.registry[full_name]
try:
result = cls.registry[full_name]
except KeyError:
raise KeyError(_('No search model matching the query'))
if not hasattr(result, 'serializer'):
result.serializer = import_string(result.serializer_string)
return result
@classmethod
def as_choices(cls):
return cls.registry
@classmethod
def all(cls):
return cls.registry.values()
def __init__(self, app_label, model_name, serializer_string, label=None, permission=None):
self.app_label = app_label
self.model_name = model_name

View File

@@ -0,0 +1,13 @@
from __future__ import unicode_literals
from django.http import Http404
from .classes import SearchModel
class SearchModelMixin(object):
def get_search_model(self):
try:
return SearchModel.get(self.kwargs['search_model'])
except KeyError as exception:
raise Http404(unicode(exception))

View File

@@ -2,7 +2,7 @@ from __future__ import unicode_literals
from django.conf.urls import patterns, url
from .api_views import APISearchView
from .api_views import APIAdvancedSearchView, APISearchView
from .views import (
AdvancedSearchView, ResultsView, SearchAgainView, SearchView
)
@@ -26,5 +26,12 @@ urlpatterns = patterns(
api_urls = patterns(
'',
url(r'^search/$', APISearchView.as_view(), name='search-view'),
url(
r'^search/(?P<search_model>[\.\w]+)/$', APISearchView.as_view(),
name='search-view'
),
url(
r'^advanced/(?P<search_model>[\.\w]+)/$', APIAdvancedSearchView.as_view(),
name='advanced-search-view'
),
)

View File

@@ -5,7 +5,7 @@ import urlparse
from django.conf import settings
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.http import Http404, HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import RedirectView
@@ -13,12 +13,13 @@ from common.generics import SimpleView, SingleObjectListView
from .classes import SearchModel
from .forms import SearchForm, AdvancedSearchForm
from .mixins import SearchModelMixin
from .settings import setting_limit
logger = logging.getLogger(__name__)
class ResultsView(SingleObjectListView):
class ResultsView(SearchModelMixin, SingleObjectListView):
def get_extra_context(self):
context = {
'hide_links': True,
@@ -48,11 +49,8 @@ class ResultsView(SingleObjectListView):
return queryset
def get_search_model(self):
return SearchModel.get(self.kwargs['search_model'])
class SearchView(SimpleView):
class SearchView(SearchModelMixin, SimpleView):
template_name = 'appearance/generic_form.html'
title = _('Search')
@@ -60,7 +58,9 @@ class SearchView(SimpleView):
self.search_model = self.get_search_model()
return {
'form': self.get_form(),
'form_action': reverse('search:results', args=(self.search_model.get_full_name(),)),
'form_action': reverse(
'search:results', args=(self.search_model.get_full_name(),)
),
'search_model': self.search_model,
'submit_icon': 'fa fa-search',
'submit_label': _('Search'),
@@ -75,9 +75,6 @@ class SearchView(SimpleView):
else:
return SearchForm()
def get_search_model(self):
return SearchModel.get(self.kwargs['search_model'])
class AdvancedSearchView(SearchView):
title = _('Advanced search')

View File

@@ -17,7 +17,7 @@ django-pure-pagination==0.3.0
django-model-utils==2.4
django-mptt==0.8.0
django-qsstats-magic==0.7.2
django-rest-swagger==0.3.4
django-rest-swagger==0.3.10
django-stronghold==0.2.7
django-suit==0.2.16
django-widget-tweaks==1.4.1