Search: Add faceted search view routing and templates
Review Request #15054 — Created May 13, 2026 and updated
Updates
RBSearchViewand adds the templates, CSS, and datagrid
infrastructure for the new faceted search results page.
RBSearchView.dispatchnow checks whether the active backend exposes
get_es_client. If it does, aFacetedSearchEngineis constructed and
_use_facetedis set toTrue. Any exception during construction falls
back silently to the existing Haystack path. Numeric queries still
redirect directly to the matching review request when accessible.
get_template_namesreturnssearch/results.htmlfor the faceted path
andsearch/results_legacy.htmlfor the Haystack path.
get_context_dataon the faceted path calls
FacetedSearchEngine.search, builds the group sidebar items with total
counts, resolves human-readable labels for searchable filter buckets
(reviewer, group, repository), and assembles the filter panel context
including current values, bucket lists, and option counts.Search results are displayed using Review Board's existing datagrid
infrastructure. Three new datagrid classes are added:
SearchReviewRequestDataGrid,SearchUsersDataGrid, and
SearchGroupDataGrid. Each takes an ES-ordered PK list and an ES total
count, builds aCase/When-ordered ORM queryset from those PKs, and
overrides pagination to use the ES total rather than aCOUNT(*). Letter
navigation for users and groups is handled server-side by injecting a
prefixorregexpfilter clause directly into the ES query, avoiding
any full result fetch regardless of dataset size.
results.htmlis the new template for the faceted path, providing the
filter sidebar and results list.results_legacy.htmlis the existing
template renamed, unchanged in behaviour. search_listview.html and
search_paginator.htmlare new search-specific datagrid templates.
search.lessadds styles for the filter sidebar, bucket counts, active
filter indicators, and the Contents filter checkbox group.
_comment.htmland_group.htmlare new partial templates for
rendering comment and group search results inline.
Ran full test suite.
Verified thatdispatchcorrectly routes to the faceted path when
Elasticsearch is available and falls back silently to the Haystack
path when it is not or when engine construction fails.Verified template selection, user attachment on search hits, numeric
query redirection, and Whoosh wildcard rewriting.Confirmed the existing Haystack path is unaffected.
Verified that review request, user, and group results all display
correctly in their respective datagrids with correct column data and
ES-ordered rows.Verified that letter navigation on the users and groups tabs filters
correctly server-side via ES prefix/regexp queries and that the active
letter is correctly highlighted after navigation.Verified that pagination reflects ES total counts rather than ORM
counts across all three result tabs.Confirmed correct behaviour when switching between result tabs,
applying sidebar filters, and navigating pages.
| Summary | ID |
|---|---|
| 105a36cb381445bd09b39770cf57516ee7401bd0 | |
| 552082fd10a7c27c8a7d40f6b783f44ee00720e8 |
| Description | From | Last Updated |
|---|---|---|
|
'django.contrib.auth.models.User' imported but unused Column: 1 Error code: F401 |
|
|
|
'django.urls.reverse' imported but unused Column: 1 Error code: F401 |
|
|
|
line too long (138 > 79 characters) Column: 80 Error code: E501 |
|
|
|
continuation line under-indented for visual indent Column: 27 Error code: E128 |
|
|
|
line too long (82 > 79 characters) Column: 80 Error code: E501 |
|
|
|
line too long (138 > 79 characters) Column: 80 Error code: E501 |
|
|
|
continuation line under-indented for visual indent Column: 27 Error code: E128 |
|
|
|
redefinition of unused 'User' from line 21 Column: 9 Error code: F811 |
|
|
|
line too long (81 > 79 characters) Column: 80 Error code: E501 |
|
|
|
local variable 'parts' is assigned to but never used Column: 9 Error code: F841 |
|
|
|
line too long (81 > 79 characters) Column: 80 Error code: E501 |
|
|
|
line break before binary operator Column: 21 Error code: W503 |
|
|
|
'haystack.query.EmptySearchQuerySet' imported but unused Column: 1 Error code: F401 |
|
|
|
multiple spaces before keyword Column: 34 Error code: E272 |
|
|
|
continuation line unaligned for hanging indent Column: 21 Error code: E131 |
|
|
|
continuation line unaligned for hanging indent Column: 21 Error code: E131 |
|
|
|
line break before binary operator Column: 21 Error code: W503 |
|
|
|
line too long (80 > 79 characters) Column: 80 Error code: E501 |
|
|
|
undefined name 'SafeString' Column: 10 Error code: F821 |
|
|
|
'django.contrib.auth.models.User' imported but unused Column: 1 Error code: F401 |
|
|
|
'django.urls.reverse' imported but unused Column: 1 Error code: F401 |
|
|
|
line too long (138 > 79 characters) Column: 80 Error code: E501 |
|
|
|
continuation line under-indented for visual indent Column: 27 Error code: E128 |
|
|
|
line too long (82 > 79 characters) Column: 80 Error code: E501 |
|
|
|
line too long (138 > 79 characters) Column: 80 Error code: E501 |
|
|
|
continuation line under-indented for visual indent Column: 27 Error code: E128 |
|
|
|
redefinition of unused 'User' from line 21 Column: 9 Error code: F811 |
|
|
|
line too long (81 > 79 characters) Column: 80 Error code: E501 |
|
|
|
local variable 'parts' is assigned to but never used Column: 9 Error code: F841 |
|
|
|
line too long (81 > 79 characters) Column: 80 Error code: E501 |
|
|
|
line break before binary operator Column: 21 Error code: W503 |
|
|
|
line too long (81 > 79 characters) Column: 80 Error code: E501 |
|
|
|
line too long (82 > 79 characters) Column: 80 Error code: E501 |
|
|
|
dictionary key 'D' repeated with different values Column: 5 Error code: F601 |
|
|
|
dictionary key 'D' repeated with different values Column: 5 Error code: F601 |
|
|
|
multiple spaces before keyword Column: 31 Error code: E272 |
|
|
|
too many blank lines (2) Column: 5 Error code: E303 |
|
|
|
expected 1 blank line, found 0 Column: 5 Error code: E301 |
|
- Commits:
-
Summary ID Author 407e9e37a703f4ae0878fc5ce4ab865cd41f92f3 DanielCasaresIglesias 9b9ccd0c68798fc5b86004152ef7f80455032c62 DanielCasaresIglesias - Diff:
-
Revision 2 (+4492 -332)
- Commits:
-
Summary ID Author 9b9ccd0c68798fc5b86004152ef7f80455032c62 DanielCasaresIglesias 0de4195f9a7315e369db6bcf7a527a92ecb2c77c DanielCasaresIglesias - Diff:
-
Revision 3 (+4496 -332)
- Commits:
-
Summary ID Author 0de4195f9a7315e369db6bcf7a527a92ecb2c77c DanielCasaresIglesias bdeb43497a0aca208a555832cbf3bd415624d722 DanielCasaresIglesias - Diff:
-
Revision 4 (+4496 -332)
Checks run (2 succeeded)
- Change Summary:
-
Added Any/All filter toggle interface.
Integrated datagrids into search results.
Updated testing. - Description:
-
~ Updates
RBSearchViewand adds the templates and CSS for the new faceted~ search results page. ~ Updates
RBSearchViewand adds the templates, CSS, and datagrid~ infrastructure for the new faceted search results page. RBSearchView.dispatchnow checks whether the active backend exposesget_es_client. If it does, aFacetedSearchEngineis constructed and~ _use_facetedis set toTrue. Any exception during construction falls back~ silently to the existing Haystack path. Numeric queries still redirect directly ~ to the matching review request when accessible. ~ _use_facetedis set toTrue. Any exception during construction falls~ back silently to the existing Haystack path. Numeric queries still ~ redirect directly to the matching review request when accessible. ~ get_template_namesreturnssearch/results.htmlfor the faceted path and~ search/results_legacy.htmlfor the Haystack path.~ get_template_namesreturnssearch/results.htmlfor the faceted path~ and search/results_legacy.htmlfor the Haystack path.~ get_context_dataon the faceted path callsFacetedSearchEngine.search,~ builds the group sidebar items with total counts, resolves human-readable ~ labels for searchable filter buckets (reviewer, group, repository), and ~ assembles the filter panel context including current values, bucket lists, and ~ option counts. ~ get_context_dataon the faceted path calls~ FacetedSearchEngine.search, builds the group sidebar items with total~ counts, resolves human-readable labels for searchable filter buckets ~ (reviewer, group, repository), and assembles the filter panel context ~ including current values, bucket lists, and option counts. ~ results.htmlis the new template for the faceted path, providing the filter~ sidebar and results list. results_legacy.htmlis the existing template~ renamed, unchanged in behaviour. ~ Search results are displayed using Review Board's existing datagrid
~ infrastructure. Three new datagrid classes are added: ~ SearchReviewRequestDataGrid,SearchUsersDataGrid, and+ SearchGroupDataGrid. Each takes an ES-ordered PK list and an ES total+ count, builds a Case/When-ordered ORM queryset from those PKs, and+ overrides pagination to use the ES total rather than a COUNT(*). Letter+ navigation for users and groups is handled server-side by injecting a + prefixorregexpfilter clause directly into the ES query, avoiding+ any full result fetch regardless of dataset size. ~ search.lessadds styles for the filter sidebar, bucket counts, active filter~ indicators, and the Contents filter checkbox group. ~ results.htmlis the new template for the faceted path, providing the~ filter sidebar and results list. results_legacy.htmlis the existing+ template renamed, unchanged in behaviour. search_listview.html and + search_paginator.htmlare new search-specific datagrid templates.~ _comment.htmland_group.htmlare new partial templates for rendering~ comment and group search results inline. ~ search.lessadds styles for the filter sidebar, bucket counts, active~ filter indicators, and the Contents filter checkbox group. + + _comment.htmland_group.htmlare new partial templates for+ rendering comment and group search results inline. - Testing Done:
-
~ Verified that
dispatchcorrectly routes to the faceted path when~ Elasticsearch is available and falls back silently to the Haystack path when it ~ is not or when engine construction fails. Verified template selection, user ~ attachment on search hits, numeric query redirection, and Whoosh wildcard ~ rewriting. Confirmed the existing Haystack path is unaffected. ~ Ran full test suite.
~ Verified that dispatchcorrectly routes to the faceted path when~ Elasticsearch is available and falls back silently to the Haystack ~ path when it is not or when engine construction fails. ~ + Verified template selection, user attachment on search hits, numeric
+ query redirection, and Whoosh wildcard rewriting. + + Confirmed the existing Haystack path is unaffected.
+ + Verified that review request, user, and group results all display
+ correctly in their respective datagrids with correct column data and + ES-ordered rows. + + Verified that letter navigation on the users and groups tabs filters
+ correctly server-side via ES prefix/regexp queries and that the active + letter is correctly highlighted after navigation. + + Verified that pagination reflects ES total counts rather than ORM
+ counts across all three result tabs. + + Confirmed correct behaviour when switching between result tabs,
+ applying sidebar filters, and navigating pages. - Commits:
-
Summary ID Author bdeb43497a0aca208a555832cbf3bd415624d722 DanielCasaresIglesias 105a36cb381445bd09b39770cf57516ee7401bd0 Daniel Casares-Iglesias 552082fd10a7c27c8a7d40f6b783f44ee00720e8 Daniel Casares-Iglesias - Diff:
-
Revision 5 (+6746 -396)