2016-08-08 20:19:33 +00:00
|
|
|
|
============================================
|
|
|
|
|
Customising ``IndexView`` - the listing view
|
|
|
|
|
============================================
|
|
|
|
|
|
|
|
|
|
For the sake of consistency, this section of the docs will refer to the listing
|
|
|
|
|
view as ``IndexView``, because that is the view class that does all the heavy
|
|
|
|
|
lifting.
|
|
|
|
|
|
|
|
|
|
You can use the following attributes and methods on the ``ModelAdmin`` class to
|
|
|
|
|
alter how your model data is treated and represented by the ``IndexView``.
|
|
|
|
|
|
|
|
|
|
.. contents::
|
|
|
|
|
:local:
|
|
|
|
|
:depth: 1
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_list_display:
|
|
|
|
|
|
|
|
|
|
---------------------------
|
|
|
|
|
``ModelAdmin.list_display``
|
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
|
|
**Expected value**: A list or tuple, where each item is the name of a field or
|
|
|
|
|
single-argument callable on your model, or a similarly simple method defined
|
|
|
|
|
on the ``ModelAdmin`` class itself.
|
|
|
|
|
|
|
|
|
|
Default value: ``('__str__',)``
|
|
|
|
|
|
2016-11-28 01:40:15 +00:00
|
|
|
|
Set ``list_display`` to control which fields are displayed in the IndexView
|
2016-08-08 20:19:33 +00:00
|
|
|
|
for your model.
|
|
|
|
|
|
|
|
|
|
Example
|
|
|
|
|
|
|
|
|
|
```
|
2016-11-28 01:40:15 +00:00
|
|
|
|
list_display = ('first_name', 'last_name')
|
2016-08-08 20:19:33 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
You have three possible values that can be used in list_display:
|
|
|
|
|
|
2016-11-28 01:40:15 +00:00
|
|
|
|
- A field of the model. For example:
|
2016-08-08 20:19:33 +00:00
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
from wagtail.contrib.modeladmin.options import ModelAdmin
|
|
|
|
|
from .models import Person
|
|
|
|
|
|
|
|
|
|
class PersonAdmin(ModelAdmin):
|
|
|
|
|
model = Person
|
|
|
|
|
list_display = ('first_name', 'last_name')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- The name of a custom method on your ``ModelAdmin`` class, that accepts a
|
|
|
|
|
single parameter for the model instance. For example:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- The name of a method on your ``Model`` class that accepts only ``self`` as
|
|
|
|
|
an argument. For example:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A few special cases to note about ``list_display``:
|
|
|
|
|
|
|
|
|
|
- If the field is a ``ForeignKey``, Django will display the output of
|
|
|
|
|
``__str__()`` (``__unicode__()`` on Python 2) of the related object.
|
|
|
|
|
|
|
|
|
|
- If the string provided is a method of the model or ``ModelAdmin`` class,
|
|
|
|
|
Django will HTML-escape the output by default. To escape user input and
|
|
|
|
|
allow your own unescaped tags, use ``format_html()``. For example:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- If the value of a field is ``None``, an empty string, or an iterable
|
|
|
|
|
without elements, Wagtail will display a dash (-) for that column. You can
|
|
|
|
|
override this by setting ``empty_value_display`` on your ``ModelAdmin``
|
|
|
|
|
class. For example:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
from wagtail.contrib.modeladmin.options import ModelAdmin
|
|
|
|
|
|
|
|
|
|
class PersonAdmin(ModelAdmin):
|
|
|
|
|
empty_value_display = 'N/A'
|
|
|
|
|
...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Or, if you'd like to change the value used depending on the field, you can
|
|
|
|
|
override ``ModelAdmin``'s ``get_empty_value_display()`` method, like so:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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(self, PersonAdmin).get_empty_value_display(field_name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The ``__str__()`` (``__unicode__()`` on Python 2) method is just as valid
|
|
|
|
|
in ``list_display`` as any other model method, so it’s perfectly OK to do
|
|
|
|
|
this:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
list_display = ('__str__', 'some_other_field')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
By default, the ability to sort results by an item in ``list_display`` is
|
2016-11-28 01:40:15 +00:00
|
|
|
|
only offered when it's a field that has an actual database value (because
|
2016-08-08 20:19:33 +00:00
|
|
|
|
sorting is done at the database level). However, if the output of the
|
2016-11-28 01:40:15 +00:00
|
|
|
|
method is representative of a database field, you can indicate this fact by
|
2016-08-08 20:19:33 +00:00
|
|
|
|
setting the ``admin_order_field`` attribute on that method, like so:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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 = ('first_name', 'colored_name')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The above will tell Wagtail to order by the ``first_name`` field when
|
|
|
|
|
trying to sort by ``colored_first_name`` in the index view.
|
|
|
|
|
|
|
|
|
|
To indicate descending order with ``admin_order_field`` you can use a
|
|
|
|
|
hyphen prefix on the field name. Using the above example, this would look
|
|
|
|
|
like:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
colored_first_name.admin_order_field = '-first_name'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
``admin_order_field`` supports query lookups to sort by values on related
|
|
|
|
|
models, too. This example includes an “author first name” column in the
|
|
|
|
|
list display and allows sorting it by first name:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
from django.db import models
|
2016-11-28 01:40:15 +00:00
|
|
|
|
|
|
|
|
|
|
2016-08-08 20:19:33 +00:00
|
|
|
|
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'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Elements of ``list_display`` can also be properties. Please note however,
|
2016-11-28 01:40:15 +00:00
|
|
|
|
that due to the way properties work in Python, setting
|
|
|
|
|
``short_description`` on a property is only possible when using the
|
2016-08-08 20:19:33 +00:00
|
|
|
|
``property()`` function and **not** with the ``@property`` decorator.
|
|
|
|
|
|
|
|
|
|
For example:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
2016-11-28 01:40:15 +00:00
|
|
|
|
|
2016-08-08 20:19:33 +00:00
|
|
|
|
class PersonAdmin(ModelAdmin):
|
|
|
|
|
list_display = ('full_name',)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_list_filter:
|
|
|
|
|
|
|
|
|
|
---------------------------
|
|
|
|
|
``ModelAdmin.list_filter``
|
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
|
|
**Expected value**: A list or tuple, where each item is the name of model field
|
2016-11-28 01:40:15 +00:00
|
|
|
|
of type ``BooleanField``, ``CharField``, ``DateField``, ``DateTimeField``,
|
2016-08-08 20:19:33 +00:00
|
|
|
|
``IntegerField`` or ``ForeignKey``.
|
|
|
|
|
|
|
|
|
|
Set ``list_filter`` to activate filters in the right sidebar of the list page
|
|
|
|
|
for your model. For example:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
class PersonAdmin(ModelAdmin):
|
|
|
|
|
list_filter = ('is_staff', 'company')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_search_fields:
|
|
|
|
|
|
|
|
|
|
----------------------------
|
|
|
|
|
``ModelAdmin.search_fields``
|
|
|
|
|
----------------------------
|
|
|
|
|
|
|
|
|
|
**Expected value**: A list or tuple, where each item is the name of a model field
|
|
|
|
|
of type ``CharField``, ``TextField``, ``RichTextField`` or ``StreamField``.
|
|
|
|
|
|
|
|
|
|
Set ``search_fields`` to enable a search box at the top of the index page
|
2016-11-28 01:40:15 +00:00
|
|
|
|
for your model. You should add names of any fields on the model that should
|
2016-08-08 20:19:33 +00:00
|
|
|
|
be searched whenever somebody submits a search query using the search box.
|
|
|
|
|
|
|
|
|
|
Searching is all handled via Django's queryset API, rather than using Wagtail's
|
|
|
|
|
search backend. This means it will work for all models, whatever search backend
|
|
|
|
|
your project is using, and without any additional setup or configuration.
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_ordering:
|
|
|
|
|
|
|
|
|
|
---------------------------
|
|
|
|
|
``ModelAdmin.ordering``
|
|
|
|
|
---------------------------
|
|
|
|
|
|
2016-11-28 01:40:15 +00:00
|
|
|
|
**Expected value**: A list or tuple in the same format as a model’s
|
2016-08-08 20:19:33 +00:00
|
|
|
|
[``ordering``](https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_display) parameter.
|
|
|
|
|
|
|
|
|
|
Set ``ordering`` to specify the default ordering of objects when listed by
|
|
|
|
|
IndexView. If not provided, the model’s default ordering will be respected.
|
|
|
|
|
|
|
|
|
|
If you need to specify a dynamic order (for example, depending on user or
|
|
|
|
|
language) you can override the ``get_ordering()`` method instead.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_list_per_page:
|
|
|
|
|
|
|
|
|
|
----------------------------
|
|
|
|
|
``ModelAdmin.list_per_page``
|
|
|
|
|
----------------------------
|
|
|
|
|
|
|
|
|
|
**Expected value**: A positive integer
|
|
|
|
|
|
|
|
|
|
Set ``list_per_page`` to control how many items appear on each paginated page
|
|
|
|
|
of the index view. By default, this is set to ``100``.
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_get_queryset:
|
|
|
|
|
|
|
|
|
|
-----------------------------
|
|
|
|
|
``ModelAdmin.get_queryset()``
|
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
|
|
**Must return**: A QuerySet
|
|
|
|
|
|
|
|
|
|
The ``get_queryset`` method returns the 'base' queryset for your model, to
|
|
|
|
|
which any filters and search queries are applied. By default, the ``all()``
|
|
|
|
|
method of your model's default manager is used. But, if for any reason you
|
|
|
|
|
only want a certain sub-set of objects to appear in the IndexView listing,
|
|
|
|
|
overriding the ``get_queryset`` method on your ``ModelAdmin`` class can help
|
|
|
|
|
you with that. The method takes an ``HttpRequest`` object as a parameter, so
|
2016-11-28 01:40:15 +00:00
|
|
|
|
limiting objects by the current logged-in user is possible.
|
2016-08-08 20:19:33 +00:00
|
|
|
|
|
|
|
|
|
For example:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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):
|
|
|
|
|
list_display = ('first_name', 'last_name')
|
|
|
|
|
|
|
|
|
|
def get_queryset(self, request):
|
|
|
|
|
qs = super(PersonAdmin, self).get_queryset(request)
|
|
|
|
|
# Only show people managed by the current user
|
|
|
|
|
return qs.filter(managed_by=request.user)
|
|
|
|
|
|
|
|
|
|
|
2016-10-09 12:53:39 +00:00
|
|
|
|
.. _modeladmin_get_extra_attrs_for_row:
|
|
|
|
|
|
|
|
|
|
----------------------------------------------------
|
|
|
|
|
``ModelAdmin.get_extra_attrs_for_row()``
|
|
|
|
|
----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
**Must return**: A dictionary
|
|
|
|
|
|
|
|
|
|
The `get_extra_attrs_for_row` method allows you to add html attributes to
|
|
|
|
|
the opening `<tr>` tag for each result, in addition to the `data-object_pk` and
|
|
|
|
|
`class` attributes already added by the `result_row_display` tag.
|
|
|
|
|
|
2016-11-28 01:40:15 +00:00
|
|
|
|
If you want to add additional CSS classes, simply provide those class names
|
2016-10-09 12:53:39 +00:00
|
|
|
|
as a string value using the `class` key, and the `odd`/`even` will be appended
|
|
|
|
|
to your custom class names when rendering.
|
|
|
|
|
|
|
|
|
|
For example, if you wanted to add some additional class names based on field
|
|
|
|
|
values, you could do something like:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2016-08-08 20:19:33 +00:00
|
|
|
|
.. _modeladmin_get_extra_class_names_for_field_col:
|
|
|
|
|
|
|
|
|
|
----------------------------------------------------
|
|
|
|
|
``ModelAdmin.get_extra_class_names_for_field_col()``
|
|
|
|
|
----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
**Must return**: A list
|
|
|
|
|
|
|
|
|
|
The ``get_extra_class_names_for_field_col`` method allows you to add additional
|
|
|
|
|
CSS class names to any of the columns defined by ``list_display`` for your
|
|
|
|
|
model. The method takes two parameters:
|
|
|
|
|
|
|
|
|
|
- ``obj``: the object being represented by the current row
|
|
|
|
|
- ``field_name``: the item from ``list_display`` being represented by the
|
|
|
|
|
current column
|
|
|
|
|
|
|
|
|
|
For example, if you'd like to apply some conditional formatting to a cell
|
|
|
|
|
depending on the row's value, you could do something like:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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):
|
|
|
|
|
field_name == 'balance':
|
|
|
|
|
if balance <= Decimal('-100.00'):
|
|
|
|
|
return ['brand-danger']
|
|
|
|
|
if balance <= Decimal('-0.00'):
|
|
|
|
|
return ['brand-warning']
|
|
|
|
|
if balance <= Decimal('-50.00'):
|
|
|
|
|
return ['brand-info']
|
|
|
|
|
else:
|
|
|
|
|
return ['brand-success']
|
|
|
|
|
return []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_get_extra_attrs_for_field_col:
|
|
|
|
|
|
|
|
|
|
----------------------------------------------------
|
|
|
|
|
``ModelAdmin.get_extra_attrs_for_field_col()``
|
|
|
|
|
----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
**Must return**: A dictionary
|
|
|
|
|
|
|
|
|
|
The ``get_extra_attrs_for_field_col`` method allows you to add additional HTML
|
|
|
|
|
attributes to any of the columns defined in ``list_display``. Like the
|
|
|
|
|
``get_extra_class_names_for_field_col`` method above, this method takes two
|
2016-11-28 01:40:15 +00:00
|
|
|
|
parameters:
|
2016-08-08 20:19:33 +00:00
|
|
|
|
|
|
|
|
|
- ``obj``: the object being represented by the current row
|
|
|
|
|
- ``field_name``: the item from ``list_display`` being represented by the
|
|
|
|
|
current column
|
|
|
|
|
|
|
|
|
|
For example, you might like to add some tooltip text to a certain column, to
|
|
|
|
|
help give the value more context:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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(PersonAdmin, self).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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Or you might like to add one or more data attributes to help implement some
|
|
|
|
|
kind of interactivity using javascript:
|
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
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(EventAdmin, self).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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_thumbnailmixin:
|
|
|
|
|
|
|
|
|
|
----------------------------------------------------
|
|
|
|
|
``wagtal.contrib.modeladmin.options.ThumbnailMixin``
|
|
|
|
|
----------------------------------------------------
|
|
|
|
|
|
|
|
|
|
If you're using ``wagtailimages.Image`` to define an image for each item in
|
2016-11-28 01:40:15 +00:00
|
|
|
|
your model, ``ThumbnailMixin`` can help you add thumbnail versions of that
|
2016-08-08 20:19:33 +00:00
|
|
|
|
image to each row in ``IndexView``. To use it, simply extend ``ThumbnailMixin``
|
|
|
|
|
as well as ``ModelAdmin`` when defining your ``ModelAdmin`` class, and
|
2016-11-28 01:40:15 +00:00
|
|
|
|
change a few attributes to change the thumbnail to your liking, like so:
|
2016-08-08 20:19:33 +00:00
|
|
|
|
|
|
|
|
|
.. code-block:: python
|
|
|
|
|
|
|
|
|
|
from django.db import models
|
|
|
|
|
from wagtail.contrib.modeladmin.options import ThumbnailMixin, 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):
|
2016-11-28 01:40:15 +00:00
|
|
|
|
|
2016-08-08 20:19:33 +00:00
|
|
|
|
# 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'
|
2016-11-28 01:40:15 +00:00
|
|
|
|
|
2016-08-08 20:19:33 +00:00
|
|
|
|
# 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 = 'http://lorempixel.com/100/100'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_list_display_add_buttons:
|
|
|
|
|
|
|
|
|
|
---------------------------------------
|
|
|
|
|
``ModelAdmin.list_display_add_buttons``
|
|
|
|
|
---------------------------------------
|
|
|
|
|
|
|
|
|
|
**Expected value**: A string matching one of the items in ``list_display``.
|
|
|
|
|
|
|
|
|
|
If for any reason you'd like to change which column the action buttons appear
|
2016-11-28 01:40:15 +00:00
|
|
|
|
in for each row, you can specify a different column using
|
2016-08-08 20:19:33 +00:00
|
|
|
|
``list_display_add_buttons`` on your ``ModelAdmin`` class. The value must
|
|
|
|
|
match one of the items your class's ``list_display`` attribute. By default,
|
2016-11-28 01:40:15 +00:00
|
|
|
|
buttons are added to the first column of each row.
|
2016-08-08 20:19:33 +00:00
|
|
|
|
|
2016-11-28 01:40:15 +00:00
|
|
|
|
See the ``ThumbnailMixin`` example above to see how
|
2016-08-08 20:19:33 +00:00
|
|
|
|
``list_display_add_buttons`` can be used.
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_index_view_extra_css:
|
|
|
|
|
|
|
|
|
|
-----------------------------------
|
|
|
|
|
``ModelAdmin.index_view_extra_css``
|
|
|
|
|
-----------------------------------
|
|
|
|
|
|
|
|
|
|
**Expected value**: A list of path names of additional stylesheets to be added
|
|
|
|
|
to the ``IndexView``
|
|
|
|
|
|
|
|
|
|
See the following part of the docs to find out more:
|
|
|
|
|
:ref:`modeladmin_adding_css_and_js`
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_index_view_extra_js:
|
|
|
|
|
|
|
|
|
|
-----------------------------------
|
|
|
|
|
``ModelAdmin.index_view_extra_js``
|
|
|
|
|
-----------------------------------
|
|
|
|
|
|
|
|
|
|
**Expected value**: A list of path names of additional js files to be added
|
|
|
|
|
to the ``IndexView``
|
|
|
|
|
|
|
|
|
|
See the following part of the docs to find out more:
|
|
|
|
|
:ref:`modeladmin_adding_css_and_js`
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_index_template_name:
|
|
|
|
|
|
|
|
|
|
---------------------------------------
|
|
|
|
|
``ModelAdmin.index_template_name``
|
|
|
|
|
---------------------------------------
|
|
|
|
|
|
|
|
|
|
**Expected value**: The path to a custom template to use for ``IndexView``
|
|
|
|
|
|
|
|
|
|
See the following part of the docs to find out more:
|
|
|
|
|
:ref:`modeladmin_overriding_templates`
|
|
|
|
|
|
|
|
|
|
.. _modeladmin_index_view_class:
|
|
|
|
|
|
|
|
|
|
---------------------------------------
|
|
|
|
|
``ModelAdmin.index_view_class``
|
|
|
|
|
---------------------------------------
|
|
|
|
|
|
2016-11-28 01:40:15 +00:00
|
|
|
|
**Expected value**: A custom ``view`` class to replace
|
2016-08-08 20:19:33 +00:00
|
|
|
|
``modeladmin.views.IndexView``
|
|
|
|
|
|
|
|
|
|
See the following part of the docs to find out more:
|
|
|
|
|
:ref:`modeladmin_overriding_views`
|
|
|
|
|
|