def get_queryset(self, raw_query=False):
        # Call the base implementation
        if not self.haystack:
            queryset = super(GenList, self).get_queryset()
        else:
            queryset = SearchQuerySet().models(self.model)

        # Optional tweak methods
        Mfields = None
        MlimitQ = None
        MsearchF = None
        MsearchQ = None
        if hasattr(self, '__fields__'):
            Mfields = self.__fields__
        if hasattr(self, '__limitQ__'):
            MlimitQ = self.__limitQ__
        if hasattr(self, '__searchF__'):
            MsearchF = self.__searchF__
        if hasattr(self, '__searchQ__'):
            MsearchQ = self.__searchQ__

        self._viewname = self.__module__

        # Link to our context and kwargs
        context = self.__context

        # Update kwargs if json key is present
        jsonquerytxt = self.request.GET.get('json', self.request.POST.get('json', None))
        if jsonquerytxt is not None:
            # Decode json
            try:
                jsonquery = json.loads(jsonquerytxt)
            except json.JSONDecodeError as e:
                raise IOError("json argument in your GET/POST parameters is not a valid JSON string")

            # Set json context
            jsondata = self.set_context_json(jsonquery)

            # Get listid
            listid = jsondata.pop('listid')
            # Get elementid
            elementid = jsondata.pop('elementid')
        else:
            listid = None
            elementid = None
            jsondata = {}
            jsonquery = {}

        # Build info for GenModel methods
        MODELINF = MODELINFO(self.model, self._appname, self._modelname, self._viewname, self.request, self.user, self.profile, jsonquery, Mfields, MlimitQ, MsearchF, MsearchQ, listid, elementid, self.__kwargs)

        # Process the filter
        context['filters'] = []
        context['filters_obj'] = {}

        # Get field list
        fields = getattr(self, 'fields', MODELINF.fields())

        # Save GET values
        context['get'] = []
        context['getval'] = {}
        for name in jsondata:
            struct = {}
            struct['name'] = name
            if name == 'rowsperpage':
                struct['value'] = self.default_rows_per_page
            elif name == 'page':
                struct['value'] = 1
            elif name == 'pages_to_bring':
                struct['value'] = 1
            else:
                struct['value'] = jsondata[name]
            context['get'].append(struct)
            context['getval'][name] = struct['value']

        # Filter on limits
        limits = MODELINF.limitQ()
        qobjects = None
        distinct = False
        for name in limits:
            if name == 'i_distinct' or name == 'e_distinct':
                distinct = True
            else:
                if qobjects:
                    qobjects &= limits[name]
                else:
                    qobjects = limits[name]

        if qobjects:
            queryset = queryset.filter(qobjects)

        if hasattr(self, 'annotations'):
            if not self.haystack:
                # Prepare annotations
                if callable(self.annotations):
                    anot = self.annotations(MODELINF)
                else:
                    anot = self.annotations

                # Set annotations
                queryset = queryset.annotate(**anot)
            else:
                raise IOError("Haystack doesn't support annotate")

        if distinct:
            queryset = queryset.distinct()

        # Filters on fields requested by the user request
        try:
            filters_get = jsondata.get('filters', '{}')
            if type(filters_get) == dict:
                filters_by_struct = filters_get
            else:
                filters_by_struct = json.loads(str(filters_get))
        except Exception:
            filters_by_struct = []

        listfilters = {}
        # Autofilter system
        if self.autofiltering:
            listfilters.update(self.autoSearchF(MODELINF))
        # List of filters from the MODELINF
        listfilters.update(MODELINF.searchF())

        # Process the search
        filters_struct = {}
        for key in filters_by_struct:
            # Get the value of the original filter
            value = filters_by_struct[key]
            # If there is something to filter, filter is not being changed and filter is known by the class
            try:
                value = int(value)
            except ValueError:
                pass
            except TypeError:
                pass

            # ORIG if (key in listfilters) and ((value>0) or (type(value) == list)):
            # V1 if (value and type(value) == int and key in listfilters) and ((value > 0) or (type(value) == list)):
            # V2 if (value and type(value) == int and key in listfilters) or ((value > 0) or (type(value) == list)):
            if value and key in listfilters:
                # Add the filter to the queryset
                rule = listfilters[key]
                # Get type
                typekind = rule[2]
                if type(typekind) == list:
                    # Compatibility: set typekind and fv in the old fassion
                    if type(value) == int:
                        fv = typekind[value - 1][0]
                        queryset = queryset.filter(rule[1](fv))
                        typekind = 'select'
                elif typekind == 'select':
                    # Get selected value from rule
                    if type(value) == int:
                        fv = rule[3][value - 1][0]
                        queryset = queryset.filter(rule[1](fv))
                elif typekind in ['multiselect', 'multidynamicselect']:
                    # Get selected values from rule
                    if type(value) in (list, tuple) and len(value):
                        qobjects = Q(rule[1](value[0]))
                        for fvt in value[1:]:
                            qobjects |= Q(rule[1](fvt))
                        queryset = queryset.filter(qobjects)
                elif typekind in ['daterange', 'input']:
                    # No arguments
                    fv = value
                    queryset = queryset.filter(rule[1](fv))
                elif typekind in ['checkbox', ]:
                    fv = value
                    queryset = queryset.filter(rule[1](fv))
                else:
                    raise IOError("Wrong typekind '{0}' for filter '{1}'".format(typekind, key))
                # Save it in the struct as a valid filter
                filters_struct[key] = value

        # Rewrite filters_json updated
        filters_json = json.dumps(filters_struct)

        # Build the clean get for filters
        get = context['get']
        filters_get = []
        for element in get:
            if element['name'] not in ['filters']:
                struct = {}
                struct['name'] = element['name']
                struct['value'] = element['value']
                filters_get.append(struct)

        # Add filter_json
        struct = {}
        struct['name'] = 'filters'
        struct['value'] = filters_json
        filters_get.append(struct)
        context['filters_get'] = filters_get

        # Get the list of filters allowed by this class
        filters = []
        for key in listfilters:
            typekind = listfilters[key][2]
            if type(typekind) == list:
                # Compatibility: set typekind and fv in the old fassion
                choice = [_('All')]
                for value in typekind:
                    choice.append(value[1])

                # Decide the choosen field
                if key in filters_struct.keys():
                    value = int(filters_struct[key])
                else:
                    value = 0
                typekind = 'select'
                argument = choice
            elif typekind == 'select':
                typevalue = listfilters[key][3]
                choice = [_('All')]
                for value in typevalue:
                    choice.append(value[1])

                # Decide the choosen field
                if key in filters_struct.keys():
                    value = int(filters_struct[key])
                else:
                    value = 0
                # Set choice as the command's argument
                argument = choice
            elif typekind in ['multiselect', 'multidynamicselect']:
                if typekind == 'multiselect':
                    typevalue = listfilters[key][3]
                    choice = []
                    for value in typevalue:
                        choice.append({'id': value[0], 'label': value[1]})
                else:
                    choice = list(listfilters[key][3:])
                    choice[1] = reverse_lazy(choice[1], kwargs={'search': 'a'})[:-1]

                # Decide the choosen field
                if key in filters_struct.keys():
                    value = filters_struct[key]
                else:
                    value = []

                # Set choice as the command's argument
                argument = choice
            elif typekind in ['daterange', 'input']:
                # Commands withouth arguments
                argument = None
                # Get the selected value
                if key in filters_struct.keys():
                    value = filters_struct[key]
                else:
                    value = None
            elif typekind in ['checkbox']:
                # Commands withouth arguments
                argument = None
                # Get the selected value
                if key in filters_struct.keys():
                    value = filters_struct[key]
                else:
                    value = None
            else:
                raise IOError("Wrong typekind '{0}' for filter '{1}'".format(typekind, key))

            # Build filtertuple
            filtertuple = (key, listfilters[key][0], typekind, argument, value)
            # Save this filter in the corresponding list
            filters.append(filtertuple)

        # Save all filters
        context['filters'] = filters

        # Search filter button
        search_filter_button = jsondata.get('search_filter_button', None)
        if search_filter_button is not None:
            self.search_filter_button = search_filter_button

        # Search text in all fields
        search = jsondata.get('search', '').lower()
        # Remove extra spaces
        newlen = len(search)
        oldlen = 0
        while newlen != oldlen:
            oldlen = newlen
            search = search.replace("  ", " ")
            newlen = len(search)
        if len(search) > 0 and search[0] == ' ':
            search = search[1:]
        if len(search) > 0 and search[-1] == ' ':
            search = search[:-1]

        # Save in context
        context['search'] = search
        datetimeQ = None
        if len(search) > 0:

            # Get ID
            tid = None
            if 'id:' in search:
                tid = search.split(":")[1].split(" ")[0]
                # Decide if it is what we expect
                try:
                    tid = int(tid)
                except Exception:
                    tid = None
                # Remove the token
                if tid:
                    search = search.replace("id:%s" % (tid), '')
                    search = search.replace("  ", " ")

            # Get PK
            tpk = None
            if 'pk:' in search:
                tpk = search.split(":")[1].split(" ")[0]
                # Decide if it is what we expect
                try:
                    tpk = int(tpk)
                except Exception:
                    tpk = None
                # Remove the token
                if tpk:
                    search = search.replace("pk:%s" % (tpk), '')
                    search = search.replace("  ", " ")

            # Spaces on front and behind
            if len(search) > 0 and search[0] == ' ':
                search = search[1:]
            if len(search) > 0 and search[-1] == ' ':
                search = search[:-1]

            searchs = {}
            # Autofilter system
            if self.autofiltering:
                searchs.update(self.autoSearchQ(MODELINF, search))

            # Fields to search in from the MODELINF
            tmp_search = MODELINF.searchQ(search)
            if type(tmp_search) == dict:
                searchs.update(tmp_search)
            else:
                searchs['autoSearchQ'] &= tmp_search
            qobjects = {}
            qobjectsCustom = {}
            for name in searchs:
                # Extract the token
                qtoken = searchs[name]
                if qtoken == 'datetime':
                    # If it is a datetime
                    datetimeQ = name
                    continue
                elif (type(qtoken) == str) or (type(qtoken) == list):
                    # Prepare query
                    if type(qtoken) == tuple:
                        (query, func) = qtoken
                    else:

                        def lambdax(x):
                            return x

                        func = lambdax
                        query = qtoken

                    # If it is a string
                    if search:
                        for word in search.split(" "):
                            # If there is a word to process
                            if len(word) > 0:
                                # Build the key for the arguments and set the word as a value for the Q search
                                if word[0] == '-':
                                    # If negated request
                                    # key="-{}".format(hashlib.md5(word[1:].encode()).hexdigest())
                                    qdict = {'{}'.format(query): func(word[1:])}
                                    qtokens_element = ~Q(**qdict)
                                else:
                                    # If positive request
                                    # key="-{}".format(hashlib.md5(word[1:].encode()).hexdigest())
                                    qdict = {'{}'.format(query): func(word)}
                                    qtokens_element = Q(**qdict)

                                # Safe the token
                                if word in qobjects:
                                    qobjects[word].append(qtokens_element)
                                else:
                                    qobjects[word] = [qtokens_element]
                else:
                    if qobjectsCustom:
                        qobjectsCustom |= searchs[name]
                    else:
                        qobjectsCustom = searchs[name]

            # Build positive/negative
            qdata = None
            if search and qobjects:
                for word in search.split(" "):
                    if word.split(":")[0] not in ['id', 'pk']:
                        if word[0] == '-':
                            negative = True
                        else:
                            negative = False
                        qword = None
                        for token in qobjects[word]:
                            if qword:
                                if negative:
                                    qword &= token
                                else:
                                    qword |= token
                            else:
                                qword = token
                        if qword:
                            if qdata:
                                qdata &= qword
                            else:
                                qdata = qword

            # Process ID/PK specific searches
            if tid:
                queryset = queryset.filter(id=tid)
            if tpk:
                queryset = queryset.filter(pk=tpk)
            # Add custom Q-objects
            if qobjectsCustom:
                queryset = queryset.filter(qobjectsCustom)
            # Add word by word search Q-objects
            if qdata:
                queryset = queryset.filter(qdata)
        else:
            # Look for datetimeQ field
            searchs = MODELINF.searchQ(search)
            for name in searchs:
                if (searchs[name] == 'datetime'):
                    datetimeQ = name
                    continue

        # Datetime Q
        context['datetimeQ'] = datetimeQ
        if datetimeQ:
            # Inicialization
            f = {}
            f['year'] = (1900, 2100, False)
            f['month'] = (1, 12, False)
            f['day'] = (1, 31, False)
            f['hour'] = (0, 23, False)
            f['minute'] = (0, 59, False)
            f['second'] = (0, 59, False)
            date_elements = [None, 'year', 'month', 'day', 'hour', 'minute', 'second']
            # Get configuration of dates and set limits to the queryset
            for element in date_elements[1:]:
                value = jsondata.get(element, None)
                if value:
                    f[element] = (int(value), int(value), True)
            if f['year'][2] and f['month'][2] and not f['day'][2]:
                (g, lastday) = calendar.monthrange(f['year'][1], f['month'][1])
                f['day'] = (f['day'][0], lastday, f['day'][2])
            # Limits
            date_min = datetime.datetime(f['year'][0], f['month'][0], f['day'][0], f['hour'][0], f['minute'][0], f['second'][0])
            date_max = datetime.datetime(f['year'][1], f['month'][1], f['day'][1], f['hour'][1], f['minute'][1], f['second'][1])
            qarg1 = {"{}__gte".format(datetimeQ): date_min}
            qarg2 = {"{}__lte".format(datetimeQ): date_max}
            qarg3 = {datetimeQ: None}
            queryset = queryset.filter((Q(**qarg1) & Q(**qarg2)) | Q(**qarg3))

            # Find actual deepness
            deepness_index = 0
            for element in date_elements[1:]:
                if f[element][2]:
                    deepness_index += 1
                else:
                    break

            # Get results from dates to set the new order
            exclusion = {}
            exclusion[datetimeQ] = None
            date_results = queryset.exclude(**exclusion).values_list(datetimeQ, flat=True)
            # Remove empty results (usefull when the date is allowed to be empty)
            if f['day'][0] != f['day'][1]:
                if f['month'][0] == f['month'][1]:
                    date_results = date_results.datetimes(datetimeQ, 'day')
                elif f['year'][0] == f['year'][1]:
                    date_results = date_results.datetimes(datetimeQ, 'month')
                else:
                    date_results = date_results.datetimes(datetimeQ, 'year')

            get = context['get']
            context['datefilter'] = {}
            # Save the deepness
            if deepness_index + 1 == len(date_elements):
                context['datefilter']['deepness'] = None
            else:
                context['datefilter']['deepness'] = date_elements[deepness_index + 1]
            context['datefilter']['deepnessback'] = []
            context['datefilter']['deepnessinit'] = []
            for element in get:
                if (not element['name'] in date_elements):
                    struct = {}
                    struct['name'] = element['name']
                    struct['value'] = element['value']
                    context['datefilter']['deepnessinit'].append(struct)
                    context['datefilter']['deepnessback'].append(struct)
                elif (element['name'] != date_elements[deepness_index] and f[element['name']][2]):
                    struct = {}
                    struct['name'] = element['name']
                    struct['value'] = element['value']
                    context['datefilter']['deepnessback'].append(struct)
            # Build the list of elements
            context['datefilter']['data'] = []
            for element in date_results:
                # Save the data
                context['datefilter']['data'].append(element.timetuple()[deepness_index])
            context['datefilter']['data'] = list(set(context['datefilter']['data']))
            context['datefilter']['data'].sort()

            # Prepare the rightnow result
            if self.json_worker:
                rightnow = {}
                for key in ['year', 'month', 'day', 'hour', 'minute', 'second']:
                    rightnow[key] = (f[key][2] and f[key][0]) or None
            else:
                if f['month'][2]:
                    month = monthname(f['month'][0])
                else:
                    month = '__'
                if f['hour'][2]:
                    rightnow = string_concat(grv(f, 'day'), "/", month, "/", grv(f, 'year'), " ", grv(f, 'hour'), ":", grv(f, 'minute'), ":", grv(f, 'second'))
                else:
                    rightnow = string_concat(grv(f, 'day'), "/", month, "/", grv(f, 'year'))
            context['datefilter']['rightnow'] = rightnow
        else:
            context['datefilter'] = None

        # Distinct
        # queryset=queryset.distinct()

        # Ordering field autofill
        try:
            order_get = jsondata.get('ordering', [])
            if type(order_get) == list:
                order_by_struct = order_get
            else:
                order_by_struct = json.loads(str(order_get))
        except Exception:
            order_by_struct = []
        order_by = []
        position = {}
        counter = 1

        # Build the columns structure and the fields list
        context['columns'] = []
        self.__fields = []
        for value in fields:
            self.__fields.append(value[0])

        # Auto build rules
        self.__autorules = self.autorules()

        for order in order_by_struct:
            name = list(order.keys())[0]
            lbl = None
            # use __autofields for ordering by alias
            for field in self.__autorules:
                if "{}:".format(name) in field:
                    name = field.split(":")[0]
                    lbl = field.split(":")[1]
                    break
            direction = order[name]

            if lbl and not lbl.startswith('get_') and not lbl.endswith('_display'):
                name = lbl

            if direction == 'asc':
                order_by.append("%s" % (remove_getdisplay(name)))
            elif direction == 'desc':
                order_by.append("-%s" % (remove_getdisplay(name)))
            position[name] = counter
            counter += 1

        if order_by:
            queryset = queryset.order_by(*order_by)
        else:
            if hasattr(self, 'default_ordering'):
                if type(self.default_ordering) == list:
                    queryset = queryset.order_by(*self.default_ordering)
                else:
                    queryset = queryset.order_by(self.default_ordering)
            else:
                queryset = queryset.order_by("pk")

        # Ordering field autofill
        sort = {}
        for value in fields:
            # Get values
            if value[0]:
                name = value[0].split(":")[0]
                order_key = name
                type_field = self.get_type_field(value[0].split(":")[-1])
            else:
                name = value[0]
                # not usable fields, example: fields.append((None, _('Selector'))) in airportslist
                hash_key = hashlib.md5(value[1].encode()).hexdigest()
                order_key = "#{}".format(hash_key)
                type_field = None

            publicname = value[1]
            if len(value) > 2:
                size = value[2]
            else:
                size = None
            if len(value) > 3:
                align = value[3]
            else:
                align = None
            # filter column
            if len(value) > 4:
                filter_column = value[4]
            else:
                filter_column = None

            # Process ordering
            ordering = []
            found = False
            for order in order_by_struct:
                subname = list(order.keys())[0]
                direction = order[subname]
                if order_key == subname:
                    if direction == 'desc':
                        direction = ''
                        sort_class = 'headerSortUp'
                    elif direction == 'asc':
                        direction = 'desc'
                        sort_class = 'headerSortDown'
                    else:
                        sort_class = ''
                        direction = 'asc'
                    found = True
                if direction == 'asc' or direction == 'desc':
                    ordering.append({subname: direction})

            if not found:
                ordering.append({order_key: 'asc'})
                sort_class = ''
            # Save the ordering method
            sort[order_key] = {}
            sort[order_key]['id'] = name
            sort[order_key]['name'] = publicname
            sort[order_key]['align'] = align
            sort[order_key]['type'] = type_field

            if filter_column:
                sort[order_key]['filter'] = filter_column

            if jsonquery is None:
                sort[order_key]['size'] = size
                sort[order_key]['class'] = sort_class
                if order_key and order_key[0] != '*':
                        sort[order_key]['ordering'] = json.dumps(ordering).replace('"', '\\"')
                if order_key in position:
                    sort[order_key]['position'] = position[order_key]

        # Save ordering in the context
        if jsonquery is not None:
            context['ordering'] = order_by_struct

        # Build the columns structure and the fields list
        context['columns'] = []
        for value in fields:
            field = value[0]
            if field:
                context['columns'].append(sort[field.split(":")[0]])
            else:
                hash_key = hashlib.md5(value[1].encode()).hexdigest()
                field = "#{}".format(hash_key)
                # selector
                context['columns'].append(sort[field])

        # Auto build rules
        # self.__autorules = self.autorules()

        # Columns
        self.__columns = ['pk']
        # self.__columns = ['id']
        self.__foreignkeys = []
        for column in self.model._meta.fields:
            self.__columns.append(column.name)
            if column.is_relation:
                self.__foreignkeys.append(column.name)

        # Localfields
        self.__related_objects = []
        for f in self.model._meta.related_objects:
            self.__related_objects.append(f.name)

        # Model properties
        model_properties = self.__columns + self.__related_objects

        # === Queryset optimization ===
        # Get autorules ordered
        autorules_keys = sorted(self.__autorules.keys())
        #
        query_renamed = {}
        query_optimizer = []
        query_verifier = []
        query_select_related = []
        fields_related_model = []

        for rule in autorules_keys:
            found = False
            # name rule origin
            rule_org = rule
            # If rule is an alias
            rulesp = rule.split(":")
            if len(rulesp) == 2:
                (alias, rule) = rulesp
            else:
                alias = rule

            # If rule has a foreign key path (check first level attributes only, nfrule = no foreign rule)
            nfrule = rule.split("__")
            do_select_related = False
            model = self.model
            if len(nfrule) > 1:
                ruletmp = []
                field_related_model = []
                for n in nfrule:
                    if model:
                        for fi in model._meta.fields:
                            if fi.name == n:
                                found = True
                                ruletmp.append(n)
                                if fi.is_relation:
                                    model = fi.related_model
                                    field_related_model.append(fi.name)
                                else:
                                    do_select_related = True
                                    model = None
                                break
                    if not found or model is None:
                        break
                if field_related_model:
                    fields_related_model.append("__".join(field_related_model))

                if ruletmp != nfrule:
                    do_select_related = False
            elif nfrule[0] in [x.name for x in self.model._meta.fields] or nfrule[0] == 'pk':
                found = True
                for fi in model._meta.fields:
                    if fi.name == nfrule[0] and fi.is_relation:
                        fields_related_model.append(nfrule[0])

            if not self.haystack and (do_select_related or rule in self.__foreignkeys):
                # Compatibility with Django 1.10
                if "__" in rule:
                    query_select_related.append("__".join(rule.split('__')[0:-1]))
                else:
                    query_select_related.append(rule)

            nfrule = nfrule[0]

            if nfrule in self.__columns:

                ############################
                # dejo comentada la restriccion, si se deja y hay una FK "nunca" usaria .extra ni .value
                # no la elimino del todo por si hubiera algun fallo mas adelante,
                # y se tuviera que parametrizarse de algun otro modo
                ############################

                # if nfrule not in self.__foreignkeys:
                if rule not in fields_related_model:
                    # Save verifier name
                    query_verifier.append(rule_org)

                # Save renamed field
                if alias != rule:
                    query_renamed[alias] = F(rule)
                    query_optimizer.append(alias)
                else:
                    # Save final name
                    query_optimizer.append(rule)

            if hasattr(self, 'annotations'):
                # Prepare annotations
                if callable(self.annotations):
                    anot = self.annotations(MODELINF)
                else:
                    anot = self.annotations

                # Process annotations
                for xnfrule in anot.keys():
                    found = True
                    if xnfrule not in query_verifier:
                        query_verifier.append(xnfrule)
                        query_optimizer.append(xnfrule)

            if not found:
                query_renamed = {}
                query_optimizer = []
                query_verifier = []
                query_select_related = []
                break

        for rename in query_renamed.keys():
            if rename in model_properties:
                if rename in self.__foreignkeys:
                    msg = "Invalid alias. The alias '{}' is a foreign key from model '{}' inside app '{}'"
                elif rename in self.__columns:
                    msg = "Invalid alias. The alias '{}' is a columns from model '{}' inside app '{}'"
                elif rename in self.__related_objects:
                    msg = "Invalid alias. The alias '{}' is a related object from model '{}' inside app '{}'"
                raise Exception(msg.format(rename, self._modelname, self._appname))

        if found and query_select_related:
            queryset = queryset.select_related(*query_select_related)

        # If we got the query_optimizer to optimize everything, use it
        # use_extra = False
        query_verifier.sort()
        autorules_keys.sort()
        if found and query_verifier == autorules_keys:
            # use_extra = True
            if query_renamed:
                # queryset=queryset.extra(select=query_renamed).values(*query_optimizer)
                queryset = queryset.annotate(**query_renamed).values(*query_optimizer)
            else:
                queryset = queryset.values(*query_optimizer)

        # Custom queryset
        if hasattr(self, 'custom_queryset'):
            queryset = self.custom_queryset(queryset, MODELINF)

        # Internal Codenerix DEBUG for Querysets
        """
        raise Exception("FOUND: {} -- __foreignkeys: {} -- __columns: {} -- autorules_keys: {} -- \
            query_select_related: {} -- query_renamed: {} -- query_optimizer: {} | use_extra: {}| -- \
            query: {} -- meta.fields: {} -- fields_related_model: {} -- query_verifier: {}\
            -- ??? {} == {}".format(
                found,
                self.__foreignkeys, self.__columns, autorules_keys,
            query_select_related, query_renamed, query_optimizer,use_extra,
            queryset.query,
            [x.name for x in self.model._meta.fields],
            fields_related_model, query_verifier,
            query_verifier.sort(),autorules_keys.sort()
            ))
        #"""

        # Check if the user requested to return a raw queryset
        if raw_query:
            return queryset
        else:
            # Check the total count of registers + rows per page
            total_rows_per_page = jsondata.get('rowsperpage', self.default_rows_per_page)
            pages_to_bring = jsondata.get('pages_to_bring', 1)
            if total_rows_per_page == 'All' or self.export:
                total_rows_per_page = queryset.count()
            paginator = Paginator(queryset, total_rows_per_page)
            total_registers = paginator.count

            # Rows per page
            if total_rows_per_page:
                try:
                    total_rows_per_page = int(total_rows_per_page)
                except Exception:
                    total_rows_per_page = 'All'
            else:
                total_rows_per_page = self.default_rows_per_page
            if total_rows_per_page == 'All':
                page_number = 1
                total_rows_per_page = total_registers
                total_rows_per_page_out = _('All')
                total_pages = 1
            else:
                total_rows_per_page = int(total_rows_per_page)  # By default 10 rows per page
                total_rows_per_page_out = total_rows_per_page
                total_pages = int(total_registers / total_rows_per_page)
                if total_registers % total_rows_per_page:
                    total_pages += 1
                page_number = jsondata.get('page', 1)  # If no page specified use first page
                if page_number == 'last':
                    page_number = total_pages
                else:
                    try:
                        page_number = int(page_number)
                    except Exception:
                        page_number = 1
                    if page_number < 1:
                        page_number = 1
                    if page_number > total_pages:
                        page_number = total_pages

            # Build the list of page counters allowed
            choice = {}
            c = self.default_rows_per_page
            chk = 1
            while total_registers >= c:
                choice[c] = c
                if chk == 1:
                    # From 5 to 10
                    c = c * 2
                    # Next level
                    chk = 2
                elif chk == 2:
                    # From 10 to 25 (10*2+10/2)
                    c = c * 2 + int(c / 2)
                    # Next level
                    chk = 3
                elif chk == 3:
                    # From 25 to 50
                    c *= 2
                    chk = 1
                # Don't give a too long choice
                if c > 2000:
                    break

            # Add all choice in any case
            if settings.ALL_PAGESALLOWED:
                choice['All'] = _('All')

            # Save the pagination in the structure
            context['rowsperpageallowed'] = choice
            context['rowsperpage'] = total_rows_per_page_out
            context['pages_to_bring'] = pages_to_bring
            context['pagenumber'] = page_number

            # Get the full number of registers and save it to context
            context['total_registers'] = total_registers
            if total_rows_per_page == 'All':
                # Remove total_rows_per_page if is all
                total_rows_per_page = None
                context['page_before'] = None
                context['page_after'] = None
                context['start_register'] = 1
                context['showing_registers'] = total_registers
            else:
                # Page before
                if page_number <= 1:
                    context['page_before'] = None
                else:
                    context['page_before'] = page_number-1
                # Page after
                if page_number >= total_pages:
                    context['page_after'] = None
                else:
                    context['page_after'] = page_number+1
                # Starting on register number
                context['start_register'] = (page_number-1)*total_rows_per_page+1
                context['showing_registers'] = total_rows_per_page

            # Calculate end
            context['end_register'] = min(context['start_register']+context['showing_registers']-1, total_registers)

            # Add pagination
            regs = []
            if paginator.count:
                desired_page_number = page_number
                try:
                    range_pages_to_bring = xrange(pages_to_bring)
                except NameError:
                    range_pages_to_bring = range(pages_to_bring)
                for p in range_pages_to_bring:
                    try:
                        regs += paginator.page(desired_page_number)
                        desired_page_number += 1
                    except PageNotAnInteger:
                        # If page is not an integer, deliver first page.
                        regs += paginator.page(1)
                        desired_page_number = 2
                    except EmptyPage:
                        # If page is out of range (e.g. 9999), deliver last page of results.
                        if pages_to_bring == 1:
                            regs += paginator.page(paginator.num_pages)
                        # Leave bucle
                        break

            # Fill pages
            if total_registers:
                context['pages'] = pages(paginator, page_number)
                try:
                    range_fill = xrange(pages_to_bring-1)
                except NameError:
                    range_fill = range(pages_to_bring-1)
                for p in range_fill:
                    page_number += 1
                    context['pages'] += pages(paginator, page_number)
            else:
                context['pages'] = []

            # Return queryset
            return regs