Skip to content

Instantly share code, notes, and snippets.

@readevalprint
Created September 25, 2013 20:39
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save readevalprint/6705691 to your computer and use it in GitHub Desktop.
Save readevalprint/6705691 to your computer and use it in GitHub Desktop.
django-haystack SearchResultSerializer from django-rest-framework
==== SNIP ====
class DistanceSerializer(serializers.Serializer):
km = serializers.FloatField()
m = serializers.FloatField()
mi = serializers.FloatField()
ft = serializers.FloatField()
class SearchResultSerializer(serializers.Serializer):
text = serializers.CharField()
pub_date = serializers.DateTimeField()
distance = fields.SerializerMethodField('_distance')
content_type = fields.CharField(source='model_name')
content_object = fields.SerializerMethodField('_content_object')
def _content_object(self, obj):
if obj.model_name == 'foo':
return FoSerializer(obj.object, many=False, context=self.context).data
if obj.model_name == 'bar':
return BarSerializer(obj.object, many=False, context=self.context).data
return {}
def __init__(self, *args, **kwargs):
self.unit = kwargs.pop('unit', None)
return super(SearchResultSerializer, self).__init__(*args, **kwargs)
def _distance(self, obj):
if self.unit:
return {self.unit: getattr(obj.distance, self.unit)}
try:
return DistanceSerializer(obj.distance, many=False).data
except Exception as e:
## Log this
return {}
=== SNIP ===
class SearchView(generics.ListAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = SearchResultSerializer
def get_queryset(self, *args, **kwargs):
# This will return a dict of the first known
# unit of distance found in the query
request = self.request
results = EmptySearchQuerySet()
if request.GET.get('q'):
form = ModelSearchForm(request.QUERY_PARAMS, searchqueryset=None, load_all=True)
if form.is_valid():
query = form.cleaned_data['q']
results = form.search()
else:
form = ModelSearchForm(searchqueryset=None, load_all=True)
if results.query.backend.include_spelling:
context['suggestion'] = form.get_suggestion()
distance = None
unit = None
try:
k,v = ((k,v) for k,v in request.QUERY_PARAMS.items() if k in D.UNITS.keys()).next()
distance = {k:v}
unit = k
except Exception as e:
logging.error(e)
point = None
try:
point = Point(float(request.QUERY_PARAMS['latitude']), float(request.QUERY_PARAMS['longitude']))
except Exception as e:
logging.error(e)
if distance and point:
results = results or SearchQuerySet()
results = results.dwithin('location', point, D(**distance)).distance('location', point)
return results
#return Response(SearchResultSerializer(sqs, many=True, unit=unit).data)
@hroncok
Copy link

hroncok commented Apr 27, 2014

Ok, So I changed class SearchView(generics.ListAPIView) to:

class SearchViewSet(mixins.ListModelMixin, viewsets.GenericViewSet)

And in urls.py I have:

router.register(r'search', views.SearchViewSet, base_name='search')

And it works. Thanks a lot for sharing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment