<s> from __future__ import absolute_import , unicode_literals <EOL> import copy <EOL> import warnings <EOL> from itertools import chain <EOL> from datetime import datetime <EOL> try : <EOL> from collections import OrderedDict <EOL> except ImportError : <EOL> from django . utils . datastructures import SortedDict as OrderedDict <EOL> from django . core . exceptions import ImproperlyConfigured <EOL> from django . utils import six <EOL> from haystack import fields as haystack_fields <EOL> from haystack . query import EmptySearchQuerySet <EOL> from haystack . utils import Highlighter <EOL> from rest_framework import serializers <EOL> from rest_framework . fields import empty <EOL> from rest_framework . utils . field_mapping import ClassLookupDict , get_field_kwargs <EOL> from . fields import ( <EOL> HaystackBooleanField , HaystackCharField , HaystackDateField , HaystackDateTimeField , <EOL> HaystackDecimalField , HaystackFloatField , HaystackIntegerField <EOL> ) <EOL> class HaystackSerializer ( serializers . Serializer ) : <EOL> """<STR_LIT>""" <EOL> _field_mapping = ClassLookupDict ( { <EOL> haystack_fields . BooleanField : HaystackBooleanField , <EOL> haystack_fields . CharField : HaystackCharField , <EOL> haystack_fields . DateField : HaystackDateField , <EOL> haystack_fields . DateTimeField : HaystackDateTimeField , <EOL> haystack_fields . DecimalField : HaystackDecimalField , <EOL> haystack_fields . EdgeNgramField : HaystackCharField , <EOL> haystack_fields . FacetBooleanField : HaystackBooleanField , <EOL> haystack_fields . FacetCharField : HaystackCharField , <EOL> haystack_fields . FacetDateField : HaystackDateField , <EOL> haystack_fields . FacetDateTimeField : HaystackDateTimeField , <EOL> haystack_fields . FacetDecimalField : HaystackDecimalField , <EOL> haystack_fields . FacetFloatField : HaystackFloatField , <EOL> haystack_fields . FacetIntegerField : HaystackIntegerField , <EOL> haystack_fields . FacetMultiValueField : HaystackCharField , <EOL> haystack_fields . FloatField : HaystackFloatField , <EOL> haystack_fields . IntegerField : HaystackIntegerField , <EOL> haystack_fields . LocationField : HaystackCharField , <EOL> haystack_fields . MultiValueField : HaystackCharField , <EOL> haystack_fields . NgramField : HaystackCharField , <EOL> } ) <EOL> def __init__ ( self , instance = None , data = empty , ** kwargs ) : <EOL> super ( HaystackSerializer , self ) . __init__ ( instance , data , ** kwargs ) <EOL> try : <EOL> if not hasattr ( self . Meta , "<STR_LIT>" ) and not hasattr ( self . Meta , "<STR_LIT>" ) : <EOL> raise ImproperlyConfigured ( "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> except AttributeError : <EOL> raise ImproperlyConfigured ( "<STR_LIT>" % self . __class__ . __name__ ) <EOL> if not self . instance : <EOL> self . instance = EmptySearchQuerySet ( ) <EOL> @ staticmethod <EOL> def _get_default_field_kwargs ( model , field ) : <EOL> """<STR_LIT>""" <EOL> kwargs = { } <EOL> if field . model_attr in model . _meta . get_all_field_names ( ) : <EOL> model_field = model . _meta . get_field_by_name ( field . model_attr ) [ <NUM_LIT:0> ] <EOL> kwargs = get_field_kwargs ( field . model_attr , model_field ) <EOL> delete_attrs = [ <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ] <EOL> for attr in delete_attrs : <EOL> if attr in kwargs : <EOL> del kwargs [ attr ] <EOL> return kwargs <EOL> def _get_index_field ( self , field_name ) : <EOL> """<STR_LIT>""" <EOL> return field_name <EOL> def _get_index_class_name ( self , index_cls ) : <EOL> """<STR_LIT>""" <EOL> cls_name = index_cls . __name__ <EOL> aliases = getattr ( self . Meta , "<STR_LIT>" , { } ) <EOL> return aliases . get ( cls_name , cls_name . split ( '<STR_LIT:.>' ) [ - <NUM_LIT:1> ] ) <EOL> def get_fields ( self ) : <EOL> """<STR_LIT>""" <EOL> fields = getattr ( self . Meta , "<STR_LIT>" , [ ] ) <EOL> exclude = getattr ( self . Meta , "<STR_LIT>" , [ ] ) <EOL> if fields and exclude : <EOL> raise ImproperlyConfigured ( "<STR_LIT>" ) <EOL> ignore_fields = getattr ( self . Meta , "<STR_LIT>" , [ ] ) <EOL> indices = getattr ( self . Meta , "<STR_LIT>" ) <EOL> declared_fields = copy . deepcopy ( self . _declared_fields ) <EOL> prefix_field_names = len ( indices ) > <NUM_LIT:1> <EOL> field_mapping = OrderedDict ( ) <EOL> for index_cls in self . Meta . index_classes : <EOL> prefix = "<STR_LIT>" <EOL> if prefix_field_names : <EOL> prefix = "<STR_LIT>" % self . _get_index_class_name ( index_cls ) <EOL> for field_name , field_type in six . iteritems ( index_cls . fields ) : <EOL> orig_name = field_name <EOL> field_name = "<STR_LIT>" % ( prefix , field_name ) <EOL> if orig_name in ignore_fields or field_name in ignore_fields : <EOL> continue <EOL> if exclude : <EOL> if orig_name in exclude or field_name in exclude : <EOL> continue <EOL> if fields : <EOL> if orig_name not in fields and field_name not in fields : <EOL> continue <EOL> model = index_cls ( ) . get_model ( ) <EOL> kwargs = self . _get_default_field_kwargs ( model , field_type ) <EOL> kwargs [ '<STR_LIT>' ] = prefix_field_names <EOL> field_mapping [ field_name ] = self . _field_mapping [ field_type ] ( ** kwargs ) <EOL> if declared_fields : <EOL> for field_name in declared_fields : <EOL> if field_name in field_mapping : <EOL> warnings . warn ( "<STR_LIT>" <EOL> "<STR_LIT>" . format ( field = field_name ) ) <EOL> field_mapping [ field_name ] = declared_fields [ field_name ] <EOL> return field_mapping <EOL> def to_representation ( self , instance ) : <EOL> """<STR_LIT>""" <EOL> if getattr ( self . Meta , "<STR_LIT>" , None ) : <EOL> ret = self . multi_serializer_representation ( instance ) <EOL> else : <EOL> ret = super ( HaystackSerializer , self ) . to_representation ( instance ) <EOL> prefix_field_names = len ( getattr ( self . Meta , "<STR_LIT>" ) ) > <NUM_LIT:1> <EOL> current_index = self . _get_index_class_name ( type ( instance . searchindex ) ) <EOL> for field in self . fields . keys ( ) : <EOL> orig_field = field <EOL> if prefix_field_names : <EOL> parts = field . split ( "<STR_LIT>" ) <EOL> if len ( parts ) > <NUM_LIT:1> : <EOL> index = parts [ <NUM_LIT:0> ] [ <NUM_LIT:1> : ] <EOL> field = parts [ <NUM_LIT:1> ] <EOL> if index == current_index : <EOL> ret [ field ] = ret [ orig_field ] <EOL> del ret [ orig_field ] <EOL> elif field not in chain ( instance . searchindex . fields . keys ( ) , self . _declared_fields . keys ( ) ) : <EOL> del ret [ orig_field ] <EOL> if getattr ( instance , "<STR_LIT>" , None ) : <EOL> ret [ "<STR_LIT>" ] = instance . highlighted [ <NUM_LIT:0> ] <EOL> return ret <EOL> def multi_serializer_representation ( self , instance ) : <EOL> serializers = self . Meta . serializers <EOL> index = instance . searchindex <EOL> serializer_class = serializers . get ( type ( index ) , None ) <EOL> if not serializer_class : <EOL> raise ImproperlyConfigured ( "<STR_LIT>" % index ) <EOL> return serializer_class ( context = self . _context ) . to_representation ( instance ) <EOL> class HaystackFacetSerializer ( serializers . Serializer ) : <EOL> """<STR_LIT>""" <EOL> serialize_objects = False <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( HaystackFacetSerializer , self ) . __init__ ( * args , ** kwargs ) <EOL> class FacetDictField ( serializers . DictField ) : <EOL> """<STR_LIT>""" <EOL> def to_representation ( self , value ) : <EOL> return dict ( [ <EOL> ( six . text_type ( key ) , self . child . to_representation ( key , val ) ) <EOL> for key , val in value . items ( ) <EOL> ] ) <EOL> class FacetListField ( serializers . ListField ) : <EOL> """<STR_LIT>""" <EOL> def to_representation ( self , key , data ) : <EOL> return [ self . child . to_representation ( key , item ) for item in data ] <EOL> class FacetFieldSerializer ( serializers . Serializer ) : <EOL> """<STR_LIT>""" <EOL> text = serializers . SerializerMethodField ( ) <EOL> count = serializers . SerializerMethodField ( ) <EOL> narrow_url = serializers . SerializerMethodField ( ) <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> self . _parent_field = None <EOL> super ( FacetFieldSerializer , self ) . __init__ ( * args , ** kwargs ) <EOL> @ property <EOL> def parent_field ( self ) : <EOL> return self . _parent_field <EOL> @ parent_field . setter <EOL> def parent_field ( self , value ) : <EOL> self . _parent_field = value <EOL> def get_text ( self , instance ) : <EOL> """<STR_LIT>""" <EOL> instance = instance [ <NUM_LIT:0> ] <EOL> if isinstance ( instance , ( six . text_type , six . string_types ) ) : <EOL> return serializers . CharField ( read_only = True ) . to_representation ( instance ) <EOL> elif isinstance ( instance , datetime ) : <EOL> return serializers . DateTimeField ( read_only = True ) . to_representation ( instance ) <EOL> return instance <EOL> def get_count ( self , instance ) : <EOL> """<STR_LIT>""" <EOL> instance = instance [ <NUM_LIT:1> ] <EOL> return serializers . IntegerField ( read_only = True ) . to_representation ( instance ) <EOL> def get_narrow_url ( self , instance ) : <EOL> """<STR_LIT>""" <EOL> text = instance [ <NUM_LIT:0> ] <EOL> query_params = self . context [ "<STR_LIT>" ] . GET . copy ( ) <EOL> page_query_param = self . context [ "<STR_LIT>" ] . paginator . page_query_param <EOL> if page_query_param in query_params : <EOL> del query_params [ page_query_param ] <EOL> selected_facets = set ( query_params . pop ( "<STR_LIT>" , [ ] ) ) <EOL> selected_facets . add ( "<STR_LIT>" % { "<STR_LIT>" : self . parent_field , "<STR_LIT:text>" : text } ) <EOL> query_params . setlist ( "<STR_LIT>" , sorted ( selected_facets ) ) <EOL> return serializers . Hyperlink ( "<STR_LIT>" % { <EOL> "<STR_LIT:path>" : self . context [ "<STR_LIT>" ] . path_info , <EOL> "<STR_LIT>" : query_params . urlencode ( ) <EOL> } , name = "<STR_LIT>" ) <EOL> def to_representation ( self , field , instance ) : <EOL> """<STR_LIT>""" <EOL> self . parent_field = field <EOL> return super ( FacetFieldSerializer , self ) . to_representation ( instance ) <EOL> self . FacetDictField = FacetDictField <EOL> self . FacetListField = FacetListField <EOL> self . FacetFieldSerializer = FacetFieldSerializer <EOL> def get_fields ( self ) : <EOL> """<STR_LIT>""" <EOL> field_mapping = OrderedDict ( ) <EOL> for field , data in self . instance . items ( ) : <EOL> field_mapping . update ( <EOL> { field : self . FacetDictField ( <EOL> child = self . FacetListField ( child = self . FacetFieldSerializer ( data ) ) , required = False ) } <EOL> ) <EOL> if self . serialize_objects is True : <EOL> field_mapping [ "<STR_LIT>" ] = serializers . SerializerMethodField ( ) <EOL> return field_mapping <EOL> def get_objects ( self , instance ) : <EOL> """<STR_LIT>""" <EOL> view = self . context [ "<STR_LIT>" ] <EOL> queryset = self . context [ "<STR_LIT>" ] <EOL> page = getattr ( view . paginator , "<STR_LIT>" , None ) <EOL> if page is not None : <EOL> serializer = view . get_serializer ( page , many = True ) <EOL> return OrderedDict ( [ <EOL> ( "<STR_LIT:count>" , view . paginator . page . paginator . count ) , <EOL> ( "<STR_LIT>" , view . paginator . get_next_link ( ) ) , <EOL> ( "<STR_LIT>" , view . paginator . get_previous_link ( ) ) , <EOL> ( "<STR_LIT>" , serializer . data ) <EOL> ] ) <EOL> serializer = view . get_serializer ( queryset , many = True ) <EOL> return serializer . data <EOL> class HaystackSerializerMixin ( object ) : <EOL> """<STR_LIT>""" <EOL> def to_representation ( self , instance ) : <EOL> obj = instance . object <EOL> return super ( HaystackSerializerMixin , self ) . to_representation ( obj ) <EOL> class HighlighterMixin ( object ) : <EOL> """<STR_LIT>""" <EOL> highlighter_class = Highlighter <EOL> highlighter_css_class = "<STR_LIT>" <EOL> highlighter_html_tag = "<STR_LIT>" <EOL> highlighter_max_length = <NUM_LIT:200> <EOL> highlighter_field = None <EOL> def get_highlighter ( self ) : <EOL> if not self . highlighter_class : <EOL> raise ImproperlyConfigured ( <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" % <EOL> { "<STR_LIT>" : self . __class__ . __name__ } <EOL> ) <EOL> return self . highlighter_class <EOL> @ staticmethod <EOL> def get_document_field ( instance ) : <EOL> """<STR_LIT>""" <EOL> for name , field in instance . searchindex . fields . items ( ) : <EOL> if field . document is True : <EOL> return name <EOL> def to_representation ( self , instance ) : <EOL> ret = super ( HighlighterMixin , self ) . to_representation ( instance ) <EOL> terms = "<STR_LIT:U+0020>" . join ( six . itervalues ( self . context [ "<STR_LIT>" ] . GET ) ) <EOL> if terms : <EOL> highlighter = self . get_highlighter ( ) ( terms , ** { <EOL> "<STR_LIT>" : self . highlighter_html_tag , <EOL> "<STR_LIT>" : self . highlighter_css_class , <EOL> "<STR_LIT:max_length>" : self . highlighter_max_length <EOL> } ) <EOL> document_field = self . get_document_field ( instance ) <EOL> if highlighter and document_field : <EOL> ret [ "<STR_LIT>" ] = highlighter . highlight ( getattr ( instance , self . highlighter_field or document_field ) ) <EOL> return ret </s>
