@mobile_template('search/{mobile/}results.html')
@vary_on_headers('X-PJAX')
@non_atomic_requests
def search(request, tag_name=None, template=None):
    APP = request.APP
    types = (amo.ADDON_EXTENSION, amo.ADDON_THEME, amo.ADDON_DICT,
             amo.ADDON_SEARCH, amo.ADDON_LPAPP)

    category = request.GET.get('cat')

    if category == 'collections':
        extra_params = {'sort': {'newest': 'created'}}
    else:
        extra_params = None
    fixed = fix_search_query(request.GET, extra_params=extra_params)
    if fixed is not request.GET:
        return http.HttpResponsePermanentRedirect(urlparams(request.path,
                                                            **fixed))

    facets = request.GET.copy()

    # In order to differentiate between "all versions" and an undefined value,
    # we use "any" instead of "" in the frontend.
    if 'appver' in facets and facets['appver'] == 'any':
        facets['appver'] = ''

    form = ESSearchForm(facets or {})
    form.is_valid()  # Let the form try to clean data.

    form_data = form.cleaned_data
    if tag_name:
        form_data['tag'] = tag_name

    if category == 'collections':
        return _collections(request)
    elif category == 'themes' or form_data.get('atype') == amo.ADDON_PERSONA:
        return _personas(request)

    sort, extra_sort = split_choices(form.sort_choices, 'created')
    if form_data.get('atype') == amo.ADDON_SEARCH:
        # Search add-ons should not be searched by ADU, so replace 'Users'
        # sort with 'Weekly Downloads'.
        sort, extra_sort = list(sort), list(extra_sort)
        sort[1] = extra_sort[1]
        del extra_sort[1]

    qs = (Addon.search_public().filter(app=APP.id)
          .facet(tags={'terms': {'field': 'tag'}},
                 platforms={'terms': {'field': 'platform'}},
                 appversions={'terms':
                              {'field': APP.id % 'appversion.%s.max'}},
                 categories={'terms': {'field': 'category', 'size': 200}}))

    filters = ['atype', 'appver', 'cat', 'sort', 'tag', 'platform']
    mapping = {'users': '-average_daily_users',
               'rating': '-bayesian_rating',
               'created': '-created',
               'name': 'name_sort',
               'downloads': '-weekly_downloads',
               'updated': '-last_updated',
               'hotness': '-hotness'}
    qs = _filter_search(request, qs, form_data, filters, mapping, types=types)

    pager = amo.utils.paginate(request, qs)

    ctx = {
        'is_pjax': request.META.get('HTTP_X_PJAX'),
        'pager': pager,
        'query': form_data,
        'form': form,
        'sort_opts': sort,
        'extra_sort_opts': extra_sort,
        'sorting': sort_sidebar(request, form_data, form),
        'sort': form_data.get('sort'),
    }
    if not ctx['is_pjax']:
        facets = pager.object_list.facets
        ctx.update({
            'tag': tag_name,
            'categories': category_sidebar(request, form_data, facets),
            'platforms': platform_sidebar(request, form_data, facets),
            'versions': version_sidebar(request, form_data, facets),
            'tags': tag_sidebar(request, form_data, facets),
        })
    return render(request, template, ctx)
dataset/ETHPy150Open mozilla/addons-server/src/olympia/search/views.py/search/swapped operands of `%`