<s> import operator <EOL> from functools import reduce <EOL> from django . core . exceptions import SuspiciousOperation , ImproperlyConfigured <EOL> from django . core . paginator import InvalidPage <EOL> from django . core . urlresolvers import reverse <EOL> from django . db import models <EOL> from django . db . models . fields import FieldDoesNotExist <EOL> from django . utils . datastructures import SortedDict <EOL> from django . utils . encoding import force_str , force_text <EOL> from django . utils . translation import ugettext , ugettext_lazy <EOL> from django . utils . http import urlencode <EOL> from django . contrib . admin import FieldListFilter <EOL> from django . contrib . admin . options import IncorrectLookupParameters <EOL> from django . contrib . admin . util import ( quote , get_fields_from_path , <EOL> lookup_needs_distinct , prepare_lookup_value ) <EOL> ALL_VAR = '<STR_LIT:all>' <EOL> ORDER_VAR = '<STR_LIT:o>' <EOL> ORDER_TYPE_VAR = '<STR_LIT>' <EOL> PAGE_VAR = '<STR_LIT:p>' <EOL> SEARCH_VAR = '<STR_LIT:q>' <EOL> TO_FIELD_VAR = '<STR_LIT:t>' <EOL> IS_POPUP_VAR = '<STR_LIT>' <EOL> ERROR_FLAG = '<STR_LIT:e>' <EOL> IGNORED_PARAMS = ( <EOL> ALL_VAR , ORDER_VAR , ORDER_TYPE_VAR , SEARCH_VAR , IS_POPUP_VAR , TO_FIELD_VAR ) <EOL> EMPTY_CHANGELIST_VALUE = ugettext_lazy ( '<STR_LIT>' ) <EOL> class ChangeList ( object ) : <EOL> def __init__ ( self , request , model , list_display , list_display_links , <EOL> list_filter , date_hierarchy , search_fields , list_select_related , <EOL> list_per_page , list_max_show_all , list_editable , model_admin ) : <EOL> self . model = model <EOL> self . opts = model . _meta <EOL> self . lookup_opts = self . opts <EOL> self . root_query_set = model_admin . queryset ( request ) <EOL> self . list_display = list_display <EOL> self . list_display_links = list_display_links <EOL> self . list_filter = list_filter <EOL> self . date_hierarchy = date_hierarchy <EOL> self . search_fields = search_fields <EOL> self . list_select_related = list_select_related <EOL> self . list_per_page = list_per_page <EOL> self . list_max_show_all = list_max_show_all <EOL> self . model_admin = model_admin <EOL> self . preserved_filters = False <EOL> try : <EOL> self . page_num = int ( request . GET . get ( PAGE_VAR , <NUM_LIT:0> ) ) <EOL> except ValueError : <EOL> self . page_num = <NUM_LIT:0> <EOL> self . show_all = ALL_VAR in request . GET <EOL> self . is_popup = IS_POPUP_VAR in request . GET <EOL> self . to_field = request . GET . get ( TO_FIELD_VAR ) <EOL> self . params = dict ( request . GET . items ( ) ) <EOL> if PAGE_VAR in self . params : <EOL> del self . params [ PAGE_VAR ] <EOL> if ERROR_FLAG in self . params : <EOL> del self . params [ ERROR_FLAG ] <EOL> if self . is_popup : <EOL> self . list_editable = ( ) <EOL> else : <EOL> self . list_editable = list_editable <EOL> self . query = request . GET . get ( SEARCH_VAR , '<STR_LIT>' ) <EOL> self . query_set = self . get_query_set ( request ) <EOL> self . get_results ( request ) <EOL> if self . is_popup : <EOL> title = ugettext ( '<STR_LIT>' ) <EOL> else : <EOL> title = ugettext ( '<STR_LIT>' ) <EOL> self . title = title % force_text ( self . opts . verbose_name ) . title ( ) <EOL> self . pk_attname = self . lookup_opts . pk . attname <EOL> def get_filters ( self , request ) : <EOL> lookup_params = self . params . copy ( ) <EOL> use_distinct = False <EOL> for ignored in IGNORED_PARAMS : <EOL> if ignored in lookup_params : <EOL> del lookup_params [ ignored ] <EOL> for key , value in lookup_params . items ( ) : <EOL> if not isinstance ( key , str ) : <EOL> del lookup_params [ key ] <EOL> lookup_params [ force_str ( key ) ] = value <EOL> if not self . model_admin . lookup_allowed ( key , value ) : <EOL> raise SuspiciousOperation ( "<STR_LIT>" % key ) <EOL> filter_specs = [ ] <EOL> if self . list_filter : <EOL> for list_filter in self . list_filter : <EOL> if callable ( list_filter ) : <EOL> spec = list_filter ( request , lookup_params , <EOL> self . model , self . model_admin ) <EOL> else : <EOL> field_path = None <EOL> if isinstance ( list_filter , ( tuple , list ) ) : <EOL> field , field_list_filter_class = list_filter <EOL> else : <EOL> field , field_list_filter_class = list_filter , FieldListFilter . create <EOL> if not isinstance ( field , models . Field ) : <EOL> field_path = field <EOL> field = get_fields_from_path ( <EOL> self . model , field_path ) [ - <NUM_LIT:1> ] <EOL> spec = field_list_filter_class ( field , request , lookup_params , <EOL> self . model , self . model_admin , field_path = field_path ) <EOL> use_distinct = ( use_distinct or <EOL> lookup_needs_distinct ( self . lookup_opts , <EOL> field_path ) ) <EOL> if spec and spec . has_output ( ) : <EOL> filter_specs . append ( spec ) <EOL> try : <EOL> for key , value in lookup_params . items ( ) : <EOL> lookup_params [ key ] = prepare_lookup_value ( key , value ) <EOL> use_distinct = ( use_distinct or <EOL> lookup_needs_distinct ( self . lookup_opts , key ) ) <EOL> return filter_specs , bool ( filter_specs ) , lookup_params , use_distinct <EOL> except FieldDoesNotExist as e : <EOL> raise IncorrectLookupParameters ( e ) <EOL> def get_query_string ( self , new_params = None , remove = None ) : <EOL> if new_params is None : <EOL> new_params = { } <EOL> if remove is None : <EOL> remove = [ ] <EOL> p = self . params . copy ( ) <EOL> for r in remove : <EOL> for k in list ( p ) : <EOL> if k . startswith ( r ) : <EOL> del p [ k ] <EOL> for k , v in new_params . items ( ) : <EOL> if v is None : <EOL> if k in p : <EOL> del p [ k ] <EOL> else : <EOL> p [ k ] = v <EOL> return '<STR_LIT>' % urlencode ( sorted ( p . items ( ) ) ) <EOL> def get_results ( self , request ) : <EOL> paginator = self . model_admin . get_paginator ( <EOL> request , self . query_set , self . list_per_page ) <EOL> result_count = paginator . count <EOL> if not self . query_set . query . where : <EOL> full_result_count = result_count <EOL> else : <EOL> full_result_count = self . root_query_set . count ( ) <EOL> can_show_all = result_count <= self . list_max_show_all <EOL> multi_page = result_count > self . list_per_page <EOL> if ( self . show_all and can_show_all ) or not multi_page : <EOL> result_list = self . query_set . _clone ( ) <EOL> else : <EOL> try : <EOL> result_list = paginator . page ( self . page_num + <NUM_LIT:1> ) . object_list <EOL> except InvalidPage : <EOL> raise IncorrectLookupParameters <EOL> self . result_count = result_count <EOL> self . full_result_count = full_result_count <EOL> self . result_list = result_list <EOL> self . can_show_all = can_show_all <EOL> self . multi_page = multi_page <EOL> self . paginator = paginator <EOL> def _get_default_ordering ( self ) : <EOL> ordering = [ ] <EOL> if self . model_admin . ordering : <EOL> ordering = self . model_admin . ordering <EOL> elif self . lookup_opts . ordering : <EOL> ordering = self . lookup_opts . ordering <EOL> return ordering <EOL> def get_ordering_field ( self , field_name ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> field = self . lookup_opts . get_field ( field_name ) <EOL> return field . name <EOL> except models . FieldDoesNotExist : <EOL> if callable ( field_name ) : <EOL> attr = field_name <EOL> elif hasattr ( self . model_admin , field_name ) : <EOL> attr = getattr ( self . model_admin , field_name ) <EOL> else : <EOL> attr = getattr ( self . model , field_name ) <EOL> return getattr ( attr , '<STR_LIT>' , None ) <EOL> def get_ordering ( self , request , queryset ) : <EOL> """<STR_LIT>""" <EOL> params = self . params <EOL> ordering = list ( self . model_admin . get_ordering ( request ) <EOL> or self . _get_default_ordering ( ) ) <EOL> if ORDER_VAR in params : <EOL> ordering = [ ] <EOL> order_params = params [ ORDER_VAR ] . split ( '<STR_LIT:.>' ) <EOL> for p in order_params : <EOL> try : <EOL> none , pfx , idx = p . rpartition ( '<STR_LIT:->' ) <EOL> field_name = self . list_display [ int ( idx ) ] <EOL> order_field = self . get_ordering_field ( field_name ) <EOL> if not order_field : <EOL> continue <EOL> ordering . append ( pfx + order_field ) <EOL> except ( IndexError , ValueError ) : <EOL> continue <EOL> ordering . extend ( queryset . query . order_by ) <EOL> pk_name = self . lookup_opts . pk . name <EOL> if not ( set ( ordering ) & set ( [ '<STR_LIT>' , '<STR_LIT>' , pk_name , '<STR_LIT:->' + pk_name ] ) ) : <EOL> ordering . append ( '<STR_LIT>' ) <EOL> return ordering <EOL> def get_ordering_field_columns ( self ) : <EOL> """<STR_LIT>""" <EOL> ordering = self . _get_default_ordering ( ) <EOL> ordering_fields = SortedDict ( ) <EOL> if ORDER_VAR not in self . params : <EOL> for field in ordering : <EOL> if field . startswith ( '<STR_LIT:->' ) : <EOL> field = field [ <NUM_LIT:1> : ] <EOL> order_type = '<STR_LIT>' <EOL> else : <EOL> order_type = '<STR_LIT>' <EOL> for index , attr in enumerate ( self . list_display ) : <EOL> if self . get_ordering_field ( attr ) == field : <EOL> ordering_fields [ index ] = order_type <EOL> break <EOL> else : <EOL> for p in self . params [ ORDER_VAR ] . split ( '<STR_LIT:.>' ) : <EOL> none , pfx , idx = p . rpartition ( '<STR_LIT:->' ) <EOL> try : <EOL> idx = int ( idx ) <EOL> except ValueError : <EOL> continue <EOL> ordering_fields [ idx ] = '<STR_LIT>' if pfx == '<STR_LIT:->' else '<STR_LIT>' <EOL> return ordering_fields <EOL> def get_query_set ( self , request ) : <EOL> ( self . filter_specs , self . has_filters , remaining_lookup_params , <EOL> use_distinct ) = self . get_filters ( request ) <EOL> qs = self . root_query_set <EOL> for filter_spec in self . filter_specs : <EOL> new_qs = filter_spec . queryset ( request , qs ) <EOL> if new_qs is not None : <EOL> qs = new_qs <EOL> try : <EOL> qs = qs . filter ( ** remaining_lookup_params ) <EOL> except ( SuspiciousOperation , ImproperlyConfigured ) : <EOL> raise <EOL> except Exception as e : <EOL> raise IncorrectLookupParameters ( e ) <EOL> if not qs . query . select_related : <EOL> if self . list_select_related : <EOL> qs = qs . select_related ( ) <EOL> else : <EOL> for field_name in self . list_display : <EOL> try : <EOL> field = self . lookup_opts . get_field ( field_name ) <EOL> except models . FieldDoesNotExist : <EOL> pass <EOL> else : <EOL> if isinstance ( field . rel , models . ManyToOneRel ) : <EOL> qs = qs . select_related ( ) <EOL> break <EOL> ordering = self . get_ordering ( request , qs ) <EOL> qs = qs . order_by ( * ordering ) <EOL> def construct_search ( field_name ) : <EOL> if field_name . startswith ( '<STR_LIT>' ) : <EOL> return "<STR_LIT>" % field_name [ <NUM_LIT:1> : ] <EOL> elif field_name . startswith ( '<STR_LIT:=>' ) : <EOL> return "<STR_LIT>" % field_name [ <NUM_LIT:1> : ] <EOL> elif field_name . startswith ( '<STR_LIT:@>' ) : <EOL> return "<STR_LIT>" % field_name [ <NUM_LIT:1> : ] <EOL> else : <EOL> return "<STR_LIT>" % field_name <EOL> if self . search_fields and self . query : <EOL> orm_lookups = [ construct_search ( str ( search_field ) ) <EOL> for search_field in self . search_fields ] <EOL> for bit in self . query . split ( ) : <EOL> or_queries = [ models . Q ( ** { orm_lookup : bit } ) <EOL> for orm_lookup in orm_lookups ] <EOL> qs = qs . filter ( reduce ( operator . or_ , or_queries ) ) <EOL> if not use_distinct : <EOL> for search_spec in orm_lookups : <EOL> if lookup_needs_distinct ( self . lookup_opts , search_spec ) : <EOL> use_distinct = True <EOL> break <EOL> if use_distinct : <EOL> return qs . distinct ( ) <EOL> else : <EOL> return qs <EOL> def url_for_result ( self , result ) : <EOL> pk = getattr ( result , self . pk_attname ) <EOL> return reverse ( '<STR_LIT>' % ( self . opts . app_label , <EOL> self . opts . module_name ) , <EOL> args = ( quote ( pk ) , ) , <EOL> current_app = self . model_admin . admin_site . name ) </s>
