Настройка 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 по умолчанию экранирует вывод. Чтобы экранировать пользовательский ввод и разрешить собственные теги без экранирования, используйте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 styled_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', 'styled_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 styled_first_name(self): return format_html( '<span style="color: #{};">{}</span>', self.color_code, self.first_name, ) styled_first_name.admin_order_field = 'first_name' class PersonAdmin(ModelAdmin): model = Person list_display = ('styled_first_name', 'last_name')Это сообщит Wagtail сортировать по полю
first_nameпри попытке сортировки поstyled_first_nameв представлении списка.Вышеизложенное сообщит Wagtail сортировать по полю
first_nameпри попытке сортировки поstyled_first_nameв представлении списка.Чтобы указать порядок сортировки по убыванию с помощью
admin_order_field, вы можете использовать префикс дефис перед именем поля. При использовании вышеприведенного примера это будет выглядеть следующим образом:.. code-block:: python
styled_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 QuerySet Django по умолчанию, см. 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.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/stable/reference/contrib/modeladmin/indexview.html