Настройка 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 для задания полей, которые должны быть экспортированы как колонки при загрузке табличного представления вашего index_view.
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 передаётся в базовый механизм поиска, чтобы ограничить поля, используемые при сопоставлении. Каждый элемент в списке должен быть проиндексирован в вашей модели с помощью индекса.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/v3.0.3/reference/contrib/modeladmin/indexview.html