Fixed #8408 -- Added ModelAdmin.show_full_result_count to avoid COUNT() query.
Thanks lidaobing for the suggestion.
This commit is contained in:
parent
d1ca70110f
commit
17557d068c
|
@ -110,6 +110,7 @@ class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
|
||||||
readonly_fields = ()
|
readonly_fields = ()
|
||||||
ordering = None
|
ordering = None
|
||||||
view_on_site = True
|
view_on_site = True
|
||||||
|
show_full_result_count = True
|
||||||
|
|
||||||
# Validation of ModelAdmin definitions
|
# Validation of ModelAdmin definitions
|
||||||
# Old, deprecated style:
|
# Old, deprecated style:
|
||||||
|
|
|
@ -87,9 +87,9 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% block result_list %}
|
{% block result_list %}
|
||||||
{% if action_form and actions_on_top and cl.full_result_count %}{% admin_actions %}{% endif %}
|
{% if action_form and actions_on_top and cl.show_admin_actions %}{% admin_actions %}{% endif %}
|
||||||
{% result_list cl %}
|
{% result_list cl %}
|
||||||
{% if action_form and actions_on_bottom and cl.full_result_count %}{% admin_actions %}{% endif %}
|
{% if action_form and actions_on_bottom and cl.show_admin_actions %}{% admin_actions %}{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block pagination %}{% pagination cl %}{% endblock %}
|
{% block pagination %}{% pagination cl %}{% endblock %}
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<input type="text" size="40" name="{{ search_var }}" value="{{ cl.query }}" id="searchbar" />
|
<input type="text" size="40" name="{{ search_var }}" value="{{ cl.query }}" id="searchbar" />
|
||||||
<input type="submit" value="{% trans 'Search' %}" />
|
<input type="submit" value="{% trans 'Search' %}" />
|
||||||
{% if show_result_count %}
|
{% if show_result_count %}
|
||||||
<span class="small quiet">{% blocktrans count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}_popup=1{% endif %}">{% blocktrans with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktrans %}</a>)</span>
|
<span class="small quiet">{% blocktrans count counter=cl.result_count %}{{ counter }} result{% plural %}{{ counter }} results{% endblocktrans %} (<a href="?{% if cl.is_popup %}_popup=1{% endif %}">{% if cl.show_full_result_count %}{% blocktrans with full_result_count=cl.full_result_count %}{{ full_result_count }} total{% endblocktrans %}{% else %}{% trans "Show all" %}{% endif %}</a>)</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for pair in cl.params.items %}
|
{% for pair in cl.params.items %}
|
||||||
{% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}"/>{% endifnotequal %}
|
{% ifnotequal pair.0 search_var %}<input type="hidden" name="{{ pair.0 }}" value="{{ pair.1 }}"/>{% endifnotequal %}
|
||||||
|
|
|
@ -177,10 +177,13 @@ class ChangeList(object):
|
||||||
# Perform a slight optimization:
|
# Perform a slight optimization:
|
||||||
# full_result_count is equal to paginator.count if no filters
|
# full_result_count is equal to paginator.count if no filters
|
||||||
# were applied
|
# were applied
|
||||||
|
if self.model_admin.show_full_result_count:
|
||||||
if self.get_filters_params() or self.params.get(SEARCH_VAR):
|
if self.get_filters_params() or self.params.get(SEARCH_VAR):
|
||||||
full_result_count = self.root_queryset.count()
|
full_result_count = self.root_queryset.count()
|
||||||
else:
|
else:
|
||||||
full_result_count = result_count
|
full_result_count = result_count
|
||||||
|
else:
|
||||||
|
full_result_count = None
|
||||||
can_show_all = result_count <= self.list_max_show_all
|
can_show_all = result_count <= self.list_max_show_all
|
||||||
multi_page = result_count > self.list_per_page
|
multi_page = result_count > self.list_per_page
|
||||||
|
|
||||||
|
@ -194,6 +197,10 @@ class ChangeList(object):
|
||||||
raise IncorrectLookupParameters
|
raise IncorrectLookupParameters
|
||||||
|
|
||||||
self.result_count = result_count
|
self.result_count = result_count
|
||||||
|
self.show_full_result_count = self.model_admin.show_full_result_count
|
||||||
|
# Admin actions are shown if there is at least one entry
|
||||||
|
# or if entries are not counted because show_full_result_count is disabled
|
||||||
|
self.show_admin_actions = self.show_full_result_count or bool(full_result_count)
|
||||||
self.full_result_count = full_result_count
|
self.full_result_count = full_result_count
|
||||||
self.result_list = result_list
|
self.result_list = result_list
|
||||||
self.can_show_all = can_show_all
|
self.can_show_all = can_show_all
|
||||||
|
|
|
@ -1160,6 +1160,19 @@ subclass::
|
||||||
:meth:`ModelAdmin.get_search_results` to provide additional or alternate
|
:meth:`ModelAdmin.get_search_results` to provide additional or alternate
|
||||||
search behavior.
|
search behavior.
|
||||||
|
|
||||||
|
.. attribute:: ModelAdmin.show_full_result_count
|
||||||
|
|
||||||
|
.. versionadded:: 1.8
|
||||||
|
|
||||||
|
Set ``show_full_result_count`` to control whether the full count of objects
|
||||||
|
should be displayed on a filtered admin page (e.g. ``99 results (103 total)``).
|
||||||
|
If this option is set to ``False``, a text like ``99 results (Show all)``
|
||||||
|
is displayed instead.
|
||||||
|
|
||||||
|
The default of ``show_full_result_count=True`` generates a query to perform
|
||||||
|
a full count on the table which can be expensive if the table contains a
|
||||||
|
large number of rows.
|
||||||
|
|
||||||
.. attribute:: ModelAdmin.view_on_site
|
.. attribute:: ModelAdmin.view_on_site
|
||||||
|
|
||||||
.. versionadded:: 1.7
|
.. versionadded:: 1.7
|
||||||
|
|
|
@ -72,6 +72,10 @@ Minor features
|
||||||
<django.contrib.admin.AdminSite.site_url>` in order to display a link to the
|
<django.contrib.admin.AdminSite.site_url>` in order to display a link to the
|
||||||
front-end site.
|
front-end site.
|
||||||
|
|
||||||
|
* You can now specify :attr:`ModelAdmin.show_full_result_count
|
||||||
|
<django.contrib.admin.ModelAdmin.show_full_result_count>` to control whether
|
||||||
|
or not the full count of objects should be displayed on a filtered admin page.
|
||||||
|
|
||||||
:mod:`django.contrib.auth`
|
:mod:`django.contrib.auth`
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
@ -327,6 +327,7 @@ class LanguageAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
|
|
||||||
class RecommendationAdmin(admin.ModelAdmin):
|
class RecommendationAdmin(admin.ModelAdmin):
|
||||||
|
show_full_result_count = False
|
||||||
search_fields = ('=titletranslation__text', '=recommender__titletranslation__text',)
|
search_fields = ('=titletranslation__text', '=recommender__titletranslation__text',)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2474,11 +2474,28 @@ class AdminSearchTest(TestCase):
|
||||||
"""
|
"""
|
||||||
Test presence of reset link in search bar ("1 result (_x total_)").
|
Test presence of reset link in search bar ("1 result (_x total_)").
|
||||||
"""
|
"""
|
||||||
|
# 1 query for session + 1 for fetching user
|
||||||
|
# + 1 for filtered result + 1 for filtered count
|
||||||
|
# + 1 for total count
|
||||||
|
with self.assertNumQueries(5):
|
||||||
response = self.client.get('/test_admin/admin/admin_views/person/?q=Gui')
|
response = self.client.get('/test_admin/admin/admin_views/person/?q=Gui')
|
||||||
self.assertContains(response,
|
self.assertContains(response,
|
||||||
"""<span class="small quiet">1 result (<a href="?">3 total</a>)</span>""",
|
"""<span class="small quiet">1 result (<a href="?">3 total</a>)</span>""",
|
||||||
html=True)
|
html=True)
|
||||||
|
|
||||||
|
def test_no_total_count(self):
|
||||||
|
"""
|
||||||
|
#8408 -- "Show all" should be displayed instead of the total count if
|
||||||
|
ModelAdmin.show_full_result_count is False.
|
||||||
|
"""
|
||||||
|
# 1 query for session + 1 for fetching user
|
||||||
|
# + 1 for filtered result + 1 for filtered count
|
||||||
|
with self.assertNumQueries(4):
|
||||||
|
response = self.client.get('/test_admin/admin/admin_views/recommendation/?q=bar')
|
||||||
|
self.assertContains(response,
|
||||||
|
"""<span class="small quiet">1 result (<a href="?">Show all</a>)</span>""",
|
||||||
|
html=True)
|
||||||
|
|
||||||
|
|
||||||
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
|
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
|
||||||
ROOT_URLCONF="admin_views.urls")
|
ROOT_URLCONF="admin_views.urls")
|
||||||
|
|
Loading…
Reference in New Issue