mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Refs #10743 -- Enabled ordering for lookups in ModelAdmin.list_display.
Co-authored-by: Natalia <124304+nessita@users.noreply.github.com> Co-authored-by: Nina Menezes <https://github.com/nmenezes0>
This commit is contained in:
parent
4ade8386eb
commit
9cefdfc43f
@ -18,6 +18,7 @@ from django.contrib.admin.views.main import (
|
||||
)
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db import models
|
||||
from django.db.models.constants import LOOKUP_SEP
|
||||
from django.template import Library
|
||||
from django.template.loader import get_template
|
||||
from django.templatetags.static import static
|
||||
@ -112,7 +113,7 @@ def result_headers(cl):
|
||||
# Set ordering for attr that is a property, if defined.
|
||||
if isinstance(attr, property) and hasattr(attr, "fget"):
|
||||
admin_order_field = getattr(attr.fget, "admin_order_field", None)
|
||||
if not admin_order_field:
|
||||
if not admin_order_field and LOOKUP_SEP not in field_name:
|
||||
is_field_sortable = False
|
||||
|
||||
if not is_field_sortable:
|
||||
|
@ -3,7 +3,7 @@ from django.contrib.auth.admin import UserAdmin
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.paginator import Paginator
|
||||
|
||||
from .models import Band, Child, Event, Parent, ProxyUser, Swallow
|
||||
from .models import Band, Child, Event, GrandChild, Parent, ProxyUser, Swallow
|
||||
|
||||
site = admin.AdminSite(name="admin")
|
||||
|
||||
@ -57,6 +57,9 @@ class GrandChildAdmin(admin.ModelAdmin):
|
||||
list_display = ["name", "parent__name", "parent__parent__name"]
|
||||
|
||||
|
||||
site.register(GrandChild, GrandChildAdmin)
|
||||
|
||||
|
||||
class CustomPaginationAdmin(ChildAdmin):
|
||||
paginator = CustomPaginator
|
||||
|
||||
|
@ -2073,3 +2073,59 @@ class SeleniumTests(AdminSeleniumTestCase):
|
||||
By.CSS_SELECTOR, "[data-filter-title='It\\'s OK']"
|
||||
).get_attribute("open")
|
||||
)
|
||||
|
||||
def test_list_display_ordering(self):
|
||||
from selenium.webdriver.common.by import By
|
||||
|
||||
parent_a = Parent.objects.create(name="Parent A")
|
||||
child_l = Child.objects.create(name="Child L", parent=None)
|
||||
child_m = Child.objects.create(name="Child M", parent=parent_a)
|
||||
GrandChild.objects.create(name="Grandchild X", parent=child_m)
|
||||
GrandChild.objects.create(name="Grandchild Y", parent=child_l)
|
||||
GrandChild.objects.create(name="Grandchild Z", parent=None)
|
||||
|
||||
self.admin_login(username="super", password="secret")
|
||||
changelist_url = reverse("admin:admin_changelist_grandchild_changelist")
|
||||
self.selenium.get(self.live_server_url + changelist_url)
|
||||
|
||||
def find_result_row_texts():
|
||||
table = self.selenium.find_element(By.ID, "result_list")
|
||||
# Drop header from the result list
|
||||
return [row.text for row in table.find_elements(By.TAG_NAME, "tr")][1:]
|
||||
|
||||
def expected_from_queryset(qs):
|
||||
return [
|
||||
" ".join("-" if i is None else i for i in item)
|
||||
for item in qs.values_list(
|
||||
"name", "parent__name", "parent__parent__name"
|
||||
)
|
||||
]
|
||||
|
||||
cases = [
|
||||
# Order ascending by `name`.
|
||||
("th.sortable.column-name", ("name",)),
|
||||
# Order descending by `name`.
|
||||
("th.sortable.column-name", ("-name",)),
|
||||
# Order ascending by `parent__name`.
|
||||
("th.sortable.column-parent__name", ("parent__name", "-name")),
|
||||
# Order descending by `parent__name`.
|
||||
("th.sortable.column-parent__name", ("-parent__name", "-name")),
|
||||
# Order ascending by `parent__parent__name`.
|
||||
(
|
||||
"th.sortable.column-parent__parent__name",
|
||||
("parent__parent__name", "-parent__name", "-name"),
|
||||
),
|
||||
# Order descending by `parent__parent__name`.
|
||||
(
|
||||
"th.sortable.column-parent__parent__name",
|
||||
("-parent__parent__name", "-parent__name", "-name"),
|
||||
),
|
||||
]
|
||||
for css_selector, ordering in cases:
|
||||
with self.subTest(ordering=ordering):
|
||||
# self.selenium.get(self.live_server_url + changelist_url)
|
||||
self.selenium.find_element(By.CSS_SELECTOR, css_selector).click()
|
||||
expected = expected_from_queryset(
|
||||
GrandChild.objects.all().order_by(*ordering)
|
||||
)
|
||||
self.assertEqual(find_result_row_texts(), expected)
|
||||
|
Loading…
Reference in New Issue
Block a user