Настройка IndexView — представление списка
Для обеспечения согласованности, в этом разделе документации представление списка будет упоминаться как IndexView, поскольку именно этот класс отвечает за основную работу.
Вы можете использовать следующие атрибуты и методы класса ModelAdmin, чтобы изменить способ обработки и отображения данных модели в представлении IndexView.
ModelAdmin.list_displayModelAdmin.list_exportModelAdmin.list_filterModelAdmin.export_filenameModelAdmin.search_fieldsModelAdmin.search_handler_classModelAdmin.extra_search_kwargsModelAdmin.orderingModelAdmin.list_per_pageModelAdmin.get_queryset()ModelAdmin.get_extra_attrs_for_row()ModelAdmin.get_extra_class_names_for_field_col()ModelAdmin.get_extra_attrs_for_field_col()wagtail.contrib.modeladmin.mixins.ThumbnailMixinModelAdmin.list_display_add_buttonsModelAdmin.index_view_extra_cssModelAdmin.index_view_extra_jsModelAdmin.index_template_nameModelAdmin.index_view_class
ModelAdmin.list_display
Ожидаемое значение: Список или кортеж, где каждый элемент — имя поля или вызываемой функции с одним аргументом для вашей модели, или аналогичный простой метод, определенный в классе ModelAdmin.
Значение по умолчанию: ('__str__',)
Установите list_display для управления полями, отображаемыми в списке IndexView для вашей модели.
Вы можете использовать три типа значений в list_display:
-
Поле модели. Например:
from wagtail.contrib.modeladmin.options import ModelAdmin from .models import Person class PersonAdmin(ModelAdmin): model = Person list_display = ('first_name', 'last_name') -
Имя пользовательского метода в вашем классе
ModelAdmin, принимающего один параметр — экземпляр модели. Например:from wagtail.contrib.modeladmin.options import ModelAdmin from .models import Person class PersonAdmin(ModelAdmin): model = Person list_display = ('upper_case_name',) def upper_case_name(self, obj): return ("%s %s" % (obj.first_name, obj.last_name)).upper() upper_case_name.short_description = 'Name' -
Имя метода в вашем классе
Model, принимающего толькоselfв качестве аргумента. Например:from django.db import models from wagtail.contrib.modeladmin.options import ModelAdmin class Person(models.Model): name = models.CharField(max_length=50) birthday = models.DateField() def decade_born_in(self): return self.birthday.strftime('%Y')[:3] + "0's" decade_born_in.short_description = 'Birth decade' class PersonAdmin(ModelAdmin): model = Person list_display = ('name', 'decade_born_in')
Несколько особых случаев, касающихся list_display:
- Если поле является
ForeignKey, Django отобразит результат метода__str__()связанного объекта. -
Если указанная строка является методом модели или класса
ModelAdmin, Django по умолчанию будет экранировать вывод HTML. Чтобы экранировать пользовательский ввод и разрешить собственные неэкранированные теги, используйтеformat_html(). Например:from django.db import models from django.utils.html import format_html from wagtail.contrib.modeladmin.options import ModelAdmin class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) def colored_name(self): return format_html( '<span style="color: #{};">{} {}</span>', self.color_code, self.first_name, self.last_name, ) class PersonAdmin(ModelAdmin): model = Person list_display = ('first_name', 'last_name', 'colored_name') -
Если значение поля —
None, пустая строка или итерируемый объект без элементов, Wagtail отобразит тире (-) для этой колонки. Вы можете переопределить это, установивempty_value_displayв вашем классеModelAdmin. Например:from wagtail.contrib.modeladmin.options import ModelAdmin class PersonAdmin(ModelAdmin): empty_value_display = 'N/A' ...Или, если вы хотите изменить используемое значение в зависимости от поля, вы можете переопределить метод
ModelAdminклассаget_empty_value_display()следующим образом:from django.db import models from wagtail.contrib.modeladmin.options import ModelAdmin class Person(models.Model): name = models.CharField(max_length=100) nickname = models.CharField(blank=True, max_length=100) likes_cat_gifs = models.NullBooleanField() class PersonAdmin(ModelAdmin): model = Person list_display = ('name', 'nickname', 'likes_cat_gifs') def get_empty_value_display(self, field_name=None): if field_name == 'nickname': return 'None given' if field_name == 'likes_cat_gifs': return 'Unanswered' return super().get_empty_value_display(field_name)Метод
__str__()так же валиден вlist_displayкак и любой другой метод модели, поэтому это вполне допустимо:list_display = ('__str__', 'some_other_field')По умолчанию сортировка результатов по элементу в
list_displayдоступна только тогда, когда это поле с фактическим значением в базе данных (потому что сортировка выполняется на уровне базы данных). Однако, если вывод метода представляет собой поле базы данных, вы можете указать это, установив атрибутadmin_order_fieldдля этого метода, как показано ниже:from django.db import models from django.utils.html import format_html from wagtail.contrib.modeladmin.options import ModelAdmin class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) color_code = models.CharField(max_length=6) def colored_first_name(self): return format_html( '<span style="color: #{};">{}</span>', self.color_code, self.first_name, ) colored_first_name.admin_order_field = 'first_name' class PersonAdmin(ModelAdmin): model = Person list_display = ('colored_first_name', 'last_name')Это укажет Wagtail на сортировку по полю
first_nameпри попытке отсортировать поcolored_first_nameв представлении списка.Чтобы указать убывающую сортировку с
admin_order_field, можно использовать префикс дефиса для имени поля. Используя предыдущий пример, это будет выглядеть так:colored_first_name.admin_order_field = '-first_name'
admin_order_fieldтакже поддерживает запросы поиска для сортировки по значениям связанных моделей. В данном примере присутствует колонка «Имя автора» в списке и возможность сортировки по имени:from django.db import models class Blog(models.Model): title = models.CharField(max_length=255) author = models.ForeignKey(Person, on_delete=models.CASCADE) def author_first_name(self, obj): return obj.author.first_name author_first_name.admin_order_field = 'author__first_name' -
Элементы
list_displayтакже могут быть свойствами. Обратите внимание, что из-за работы свойств в Python установкаshort_descriptionна свойстве возможна только при использовании функцииproperty()и **не** декоратора@property.Например:
from django.db import models from wagtail.contrib.modeladmin.options import ModelAdmin class Person(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) def full_name_property(self): return self.first_name + ' ' + self.last_name full_name_property.short_description = "Full name of the person" full_name = property(full_name_property) class PersonAdmin(ModelAdmin): list_display = ('full_name',)
ModelAdmin.list_export
Ожидаемое значение: Список или кортеж, где каждый элемент — имя поля или вызываемой функции с одним аргументом для вашей модели, или аналогичный простой метод, определенный в классе ModelAdmin.
Установите list_export для указания полей, которые будут экспортированы в виде столбцов при скачивании таблицы из представления списка.
class PersonAdmin(ModelAdmin):
list_export = ('is_staff', 'company')
ModelAdmin.list_filter
Ожидаемое значение: Список или кортеж, где каждый элемент — имя поля модели типа BooleanField, CharField, DateField, DateTimeField, IntegerField или ForeignKey.
Установите list_filter для активации фильтров в правом боковом меню страницы списка вашей модели. Например:
class PersonAdmin(ModelAdmin):
list_filter = ('is_staff', 'company')
ModelAdmin.export_filename
Ожидаемое значение: Строка, задающая имя файла экспортированной таблицы без расширения.
class PersonAdmin(ModelAdmin):
export_filename = 'people_spreadsheet'
ModelAdmin.search_fields
Ожидаемое значение: Список или кортеж, где каждый элемент — имя поля модели типа CharField, TextField, RichTextField или StreamField.
Установите search_fields для включения поля поиска в верхней части страницы списка вашей модели. Вам необходимо добавить имена полей модели, которые должны учитываться при поиске, когда пользователь отправляет запрос.
Поиск обрабатывается через API Django QuerySet по умолчанию, см. ModelAdmin.search_handler_class для изменения этого поведения. Это означает, что по умолчанию это будет работать для всех моделей, независимо от используемого поискового бэкенда в вашем проекте и без дополнительной настройки.
ModelAdmin.search_handler_class
Ожидаемое значение: Подкласс wagtail.contrib.modeladmin.helpers.search.BaseSearchHandler.
Значение по умолчанию — DjangoORMSearchHandler, которое использует Django ORM для выполнения запросов к полям, указанным в search_fields.
Если вы предпочитаете использовать встроенный поисковый бэкенд Wagtail для поиска моделей, вы можете использовать класс WagtailBackendSearchHandler вместо него. Например:
from wagtail.contrib.modeladmin.helpers import WagtailBackendSearchHandler
from .models import Person
class PersonAdmin(ModelAdmin):
model = Person
search_handler_class = WagtailBackendSearchHandler
Дополнительные соображения при использовании WagtailBackendSearchHandler
ModelAdmin.search_fields используется по-другому
Значение search_fields передается в основной поисковый бэкенд для ограничения полей, используемых при сопоставлении. Каждый элемент списка должен быть индексирован в вашей модели с помощью index.SearchField.
Для поиска по **любому** индексированному полю, установите атрибут search_fields класса ModelAdmin в None, или удалите его полностью.
Индексирование дополнительных полей с помощью index.FilterField
Основной поисковый бэкенд должен уметь интерпретировать все поля и отношения, используемые в запросе, созданном методом IndexView, включая те, что используются в методах запроса prefetch() или select_related(), или в методах list_display, list_filter или ordering.
Убедитесь, что вы тщательно тестируете все в среде разработки (желательно с использованием того же поискового бэкенда, что и в рабочей среде). Wagtail выведет IndexError , если бэкенд столкнется с чем-то непонятным, и сообщит вам, что нужно изменить.
ModelAdmin.extra_search_kwargs
Ожидаемое значение: Словарь ключевых аргументов, которые будут переданы в метод search() класса search_handler_class.
Например, чтобы переопределить оператор WagtailBackendSearchHandler по умолчанию, можно сделать следующее:
from wagtail.contrib.modeladmin.helpers import WagtailBackendSearchHandler
from wagtail.search.utils import OR
from .models import IndexedModel
class DemoAdmin(ModelAdmin):
model = IndexedModel
search_handler_class = WagtailBackendSearchHandler
extra_search_kwargs = {'operator': OR}
ModelAdmin.ordering
Ожидаемое значение: Список или кортеж в том же формате, что и параметр ordering модели.
Установите ordering для указания стандартного порядка сортировки объектов при отображении в IndexView. Если не указано, будет использован стандартный порядок сортировки модели.
Если вам нужна динамическая сортировка (например, в зависимости от пользователя или языка), переопределите метод get_ordering() вместо этого.
ModelAdmin.list_per_page
Ожидаемое значение: Положительное целое число.
Установите list_per_page для управления количеством элементов на каждой страниц списка представления. По умолчанию это 100.
ModelAdmin.get_queryset()
Должно возвращать: Объект QuerySet
Метод get_queryset возвращает «базовый» QuerySet для вашей модели, к которому применяются любые фильтры и поисковые запросы. По умолчанию используется метод all() менеджера по умолчанию вашей модели. Однако, если по какой-либо причине вы хотите, чтобы в списке IndexView отображался только определенный подмножество объектов, переопределение метода get_queryset в вашем классе ModelAdmin поможет вам с этим. Метод принимает объект HttpRequest в качестве параметра, поэтому можно ограничить объекты текущим вошедшим пользователем.
Например:
from django.db import models
from wagtail.contrib.modeladmin.options import ModelAdmin
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
managed_by = models.ForeignKey('auth.User', on_delete=models.CASCADE)
class PersonAdmin(ModelAdmin):
model = Person
list_display = ('first_name', 'last_name')
def get_queryset(self, request):
qs = super().get_queryset(request)
# Only show people managed by the current user
return qs.filter(managed_by=request.user)
ModelAdmin.get_extra_attrs_for_row()
Должно возвращать: Словарь
Метод get_extra_attrs_for_row позволяет добавлять атрибуты HTML к открывающему тегу <tr> для каждого результата, помимо атрибутов data-object_pk и class, которые уже добавлены тегом шаблона result_row_display.
Если вы хотите добавить дополнительные классы CSS, просто укажите эти имена классов в качестве строкового значения, используя ключ 'class', и odd/even будут добавлены к вашим пользовательским именам классов при рендеринге.
Например, если вы хотите добавить дополнительные имена классов, основанные на значениях полей, вы можете сделать что-то вроде:
from decimal import Decimal
from django.db import models
from wagtail.contrib.modeladmin.options import ModelAdmin
class BankAccount(models.Model):
name = models.CharField(max_length=50)
account_number = models.CharField(max_length=50)
balance = models.DecimalField(max_digits=5, num_places=2)
class BankAccountAdmin(ModelAdmin):
list_display = ('name', 'account_number', 'balance')
def get_extra_attrs_for_row(self, obj, context):
if obj.balance < Decimal('0.00'):
classname = 'balance-negative'
else:
classname = 'balance-positive'
return {
'class': classname,
}
ModelAdmin.get_extra_class_names_for_field_col()
Должно возвращать: Список
Метод get_extra_class_names_for_field_col позволяет добавлять дополнительные имена классов CSS к любому из столбцов, определённых list_display для вашей модели. Метод принимает два параметра:
-
obj: объект, представляющий текущую строку -
field_name: элемент изlist_display, представляющий текущий столбец
Например, если вы хотите применить условное форматирование к ячейке в зависимости от значения строки, вы можете сделать что-то вроде:
from decimal import Decimal
from django.db import models
from wagtail.contrib.modeladmin.options import ModelAdmin
class BankAccount(models.Model):
name = models.CharField(max_length=50)
account_number = models.CharField(max_length=50)
balance = models.DecimalField(max_digits=5, num_places=2)
class BankAccountAdmin(ModelAdmin):
list_display = ('name', 'account_number', 'balance')
def get_extra_class_names_for_field_col(self, obj, field_name):
if field_name == 'balance':
if obj.balance <= Decimal('-100.00'):
return ['brand-danger']
elif obj.balance <= Decimal('-0.00'):
return ['brand-warning']
elif obj.balance <= Decimal('50.00'):
return ['brand-info']
else:
return ['brand-success']
return []
ModelAdmin.get_extra_attrs_for_field_col()
Должно возвращать: Словарь
Метод get_extra_attrs_for_field_col позволяет добавлять дополнительные атрибуты HTML к любому из столбцов, определённых в list_display. Как и метод get_extra_class_names_for_field_col выше, этот метод принимает два параметра:
-
obj: объект, представляющий текущую строку -
field_name: элемент изlist_display, представляющий текущий столбец
Например, вы можете добавить текст подсказки в определённый столбец, чтобы предоставить больше контекста значения:
from django.db import models
from wagtail.contrib.modeladmin.options import ModelAdmin
class Person(models.Model):
name = models.CharField(max_length=100)
likes_cat_gifs = models.NullBooleanField()
class PersonAdmin(ModelAdmin):
model = Person
list_display = ('name', 'likes_cat_gifs')
def get_extra_attrs_for_field_col(self, obj, field_name=None):
attrs = super().get_extra_attrs_for_field_col(obj, field_name)
if field_name == 'likes_cat_gifs' and obj.likes_cat_gifs is None:
attrs.update({
'title': (
'The person was shown several cat gifs, but failed to '
'indicate a preference.'
),
})
return attrs
Или вы можете добавить один или несколько атрибутов данных, чтобы реализовать какой-либо тип интерактивности с использованием JavaScript:
from django.db import models
from wagtail.contrib.modeladmin.options import ModelAdmin
class Event(models.Model):
title = models.CharField(max_length=255)
start_date = models.DateField()
end_date = models.DateField()
start_time = models.TimeField()
end_time = models.TimeField()
class EventAdmin(ModelAdmin):
model = Event
list_display = ('title', 'start_date', 'end_date')
def get_extra_attrs_for_field_col(self, obj, field_name=None):
attrs = super().get_extra_attrs_for_field_col(obj, field_name)
if field_name == 'start_date':
# Add the start time as data to the 'start_date' cell
attrs.update({ 'data-time': obj.start_time.strftime('%H:%M') })
elif field_name == 'end_date':
# Add the end time as data to the 'end_date' cell
attrs.update({ 'data-time': obj.end_time.strftime('%H:%M') })
return attrs
wagtail.contrib.modeladmin.mixins.ThumbnailMixin
Если вы используете wagtailimages.Image для определения изображения для каждого элемента в вашей модели, ThumbnailMixin поможет вам добавить миниатюры этого изображения к каждой строке в IndexView. Чтобы использовать его, просто расширьте ThumbnailMixin и ModelAdmin, определяя свой класс ModelAdmin, и измените несколько атрибутов, чтобы изменить миниатюру по своему усмотрению, например:
from django.db import models
from wagtail.contrib.modeladmin.mixins import ThumbnailMixin
from wagtail.contrib.modeladmin.options import ModelAdmin
class Person(models.Model):
name = models.CharField(max_length=255)
avatar = models.ForeignKey('wagtailimages.Image', on_delete=models.SET_NULL, null=True)
likes_cat_gifs = models.NullBooleanField()
class PersonAdmin(ThumbnailMixin, ModelAdmin):
# Add 'admin_thumb' to list_display, where you want the thumbnail to appear
list_display = ('admin_thumb', 'name', 'likes_cat_gifs')
# Optionally tell IndexView to add buttons to a different column (if the
# first column contains the thumbnail, the buttons are likely better off
# displayed elsewhere)
list_display_add_buttons = 'name'
"""
Set 'thumb_image_field_name' to the name of the ForeignKey field that
links to 'wagtailimages.Image'
"""
thumb_image_field_name = 'avatar'
# Optionally override the filter spec used to create each thumb
thumb_image_filter_spec = 'fill-100x100' # this is the default
# Optionally override the 'width' attribute value added to each `<img>` tag
thumb_image_width = 50 # this is the default
# Optionally override the class name added to each `<img>` tag
thumb_classname = 'admin-thumb' # this is the default
# Optionally override the text that appears in the column header
thumb_col_header_text = 'image' # this is the default
# Optionally specify a fallback image to be used when the object doesn't
# have an image set, or the image has been deleted. It can an image from
# your static files folder, or an external URL.
thumb_default = 'https://lorempixel.com/100/100'
ModelAdmin.list_display_add_buttons
Если по какой-либо причине вы хотите изменить столбец, в котором отображаются кнопки действий для каждой строки, вы можете указать другой столбец, используя list_display_add_buttons в своём классе ModelAdmin. Значение должно совпадать с одним из элементов атрибута list_display вашего класса. По умолчанию кнопки добавляются в первый столбец каждой строки.
См. пример ThumbnailMixin выше, чтобы увидеть, как можно использовать list_display_add_buttons.
ModelAdmin.index_view_extra_css
Ожидаемое значение: Список имен путей дополнительных таблиц стилей, которые нужно добавить в IndexView
См. следующую часть документации для получения дополнительной информации: Добавление дополнительных таблиц стилей и/или JavaScript
ModelAdmin.index_view_extra_js
Ожидаемое значение: Список имен путей дополнительных js-файлов, которые нужно добавить в IndexView
См. следующую часть документации для получения дополнительной информации: Добавление дополнительных таблиц стилей и/или JavaScript
ModelAdmin.index_template_name
Ожидаемое значение: Путь к настраиваемому шаблону, который нужно использовать для IndexView
См. следующую часть документации для получения дополнительной информации: Переопределение шаблонов
ModelAdmin.index_view_class
Ожидаемое значение: Настраиваемый класс view для замены modeladmin.views.IndexView
См. следующую часть документации для получения дополнительной информации: Переопределение представлений
© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/v2.16.3/reference/contrib/modeladmin/indexview.html