Initial commit
This commit is contained in:
53
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__init__.py
vendored
Normal file
53
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__init__.py
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
from django.urls import include, path
|
||||
|
||||
from wagtail import hooks
|
||||
from wagtail.admin.viewsets.base import ViewSetGroup
|
||||
|
||||
|
||||
class ViewSetRegistry:
|
||||
def __init__(self):
|
||||
self.viewsets = []
|
||||
|
||||
def populate(self):
|
||||
for fn in hooks.get_hooks("register_admin_viewset"):
|
||||
viewset = fn()
|
||||
if isinstance(viewset, (list, tuple)):
|
||||
for vs in viewset:
|
||||
self.register(vs)
|
||||
else:
|
||||
self.register(viewset)
|
||||
|
||||
def register(self, viewset):
|
||||
# Allow registering a ViewSetGroup, which will register all of its
|
||||
# registerables.
|
||||
if isinstance(viewset, ViewSetGroup):
|
||||
for vs in viewset.registerables:
|
||||
self.register(vs)
|
||||
viewset.on_register()
|
||||
return
|
||||
|
||||
self.viewsets.append(viewset)
|
||||
viewset.on_register()
|
||||
return viewset
|
||||
|
||||
def get_urlpatterns(self):
|
||||
urlpatterns = []
|
||||
|
||||
for viewset in self.viewsets:
|
||||
vs_urlpatterns = viewset.get_urlpatterns()
|
||||
|
||||
if vs_urlpatterns:
|
||||
urlpatterns.append(
|
||||
path(
|
||||
f"{viewset.url_prefix}/",
|
||||
include(
|
||||
(vs_urlpatterns, viewset.url_namespace),
|
||||
namespace=viewset.url_namespace,
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
return urlpatterns
|
||||
|
||||
|
||||
viewsets = ViewSetRegistry()
|
||||
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/__init__.cpython-310.pyc
vendored
Normal file
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/__init__.cpython-310.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/base.cpython-310.pyc
vendored
Normal file
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/base.cpython-310.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/chooser.cpython-310.pyc
vendored
Normal file
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/chooser.cpython-310.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/model.cpython-310.pyc
vendored
Normal file
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/model.cpython-310.pyc
vendored
Normal file
Binary file not shown.
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/pages.cpython-310.pyc
vendored
Normal file
BIN
env/lib/python3.10/site-packages/wagtail/admin/viewsets/__pycache__/pages.cpython-310.pyc
vendored
Normal file
Binary file not shown.
148
env/lib/python3.10/site-packages/wagtail/admin/viewsets/base.py
vendored
Normal file
148
env/lib/python3.10/site-packages/wagtail/admin/viewsets/base.py
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
from wagtail.admin.menu import WagtailMenuRegisterable, WagtailMenuRegisterableGroup
|
||||
|
||||
|
||||
class ViewSet(WagtailMenuRegisterable):
|
||||
"""
|
||||
Defines a viewset to be registered with the Wagtail admin.
|
||||
|
||||
All properties of the viewset can be defined as class-level attributes, or passed as
|
||||
keyword arguments to the constructor (in which case they will override any class-level
|
||||
attributes). Additionally, the :attr:`name` property can be passed as the first positional
|
||||
argument to the constructor.
|
||||
|
||||
For more information on how to use this class, see :ref:`using_base_viewset`.
|
||||
"""
|
||||
|
||||
#: A special value that, when passed in a kwargs dict to construct a view, indicates that
|
||||
#: the attribute should not be written and should instead be left as the view's initial value
|
||||
UNDEFINED = object()
|
||||
|
||||
#: A name for this viewset, used as the default URL prefix and namespace.
|
||||
name = None
|
||||
|
||||
#: The icon to use across the views.
|
||||
icon = ""
|
||||
|
||||
def __init__(self, name=None, **kwargs):
|
||||
if name:
|
||||
self.__dict__["name"] = name
|
||||
|
||||
for key, value in kwargs.items():
|
||||
self.__dict__[key] = value
|
||||
|
||||
def get_common_view_kwargs(self, **kwargs):
|
||||
"""
|
||||
Returns a dictionary of keyword arguments to be passed to all views within this viewset.
|
||||
"""
|
||||
return kwargs
|
||||
|
||||
def construct_view(self, view_class, **kwargs):
|
||||
"""
|
||||
Wrapper for view_class.as_view() which passes the kwargs returned from get_common_view_kwargs
|
||||
in addition to any kwargs passed to this method. Items from get_common_view_kwargs will be
|
||||
filtered to only include those that are valid for the given view_class.
|
||||
"""
|
||||
merged_kwargs = self.get_common_view_kwargs()
|
||||
merged_kwargs.update(kwargs)
|
||||
filtered_kwargs = {
|
||||
key: value
|
||||
for key, value in merged_kwargs.items()
|
||||
if hasattr(view_class, key) and value is not self.UNDEFINED
|
||||
}
|
||||
return view_class.as_view(**filtered_kwargs)
|
||||
|
||||
def inject_view_methods(self, view_class, method_names):
|
||||
"""
|
||||
Check for the presence of any of the named methods on this viewset. If any are found,
|
||||
create a subclass of view_class that overrides those methods to call the implementation
|
||||
on this viewset instead. Otherwise, return view_class unmodified.
|
||||
"""
|
||||
viewset = self
|
||||
overrides = {}
|
||||
for method_name in method_names:
|
||||
viewset_method = getattr(viewset, method_name, None)
|
||||
if viewset_method:
|
||||
|
||||
def view_method(self, *args, **kwargs):
|
||||
return viewset_method(*args, **kwargs)
|
||||
|
||||
view_method.__name__ = method_name
|
||||
overrides[method_name] = view_method
|
||||
|
||||
if overrides:
|
||||
return type(view_class.__name__, (view_class,), overrides)
|
||||
else:
|
||||
return view_class
|
||||
|
||||
@cached_property
|
||||
def url_prefix(self):
|
||||
"""
|
||||
The preferred URL prefix for views within this viewset. When registered through
|
||||
Wagtail's :ref:`register_admin_viewset` hook, this will be used as the URL path component
|
||||
following ``/admin/``. Other URL registration mechanisms (e.g. editing ``urls.py`` manually)
|
||||
may disregard this and use a prefix of their own choosing.
|
||||
|
||||
Defaults to the viewset's ``name``.
|
||||
"""
|
||||
if not self.name:
|
||||
raise ImproperlyConfigured(
|
||||
"ViewSet %r must provide a `name` property" % self
|
||||
)
|
||||
return self.name
|
||||
|
||||
@cached_property
|
||||
def url_namespace(self):
|
||||
"""
|
||||
The URL namespace for views within this viewset. Will be used internally as the
|
||||
application namespace for the viewset's URLs, and generally be the instance namespace
|
||||
too.
|
||||
|
||||
Defaults to the viewset's ``name``.
|
||||
"""
|
||||
if not self.name:
|
||||
raise ImproperlyConfigured(
|
||||
"ViewSet %r must provide a `name` property" % self
|
||||
)
|
||||
return self.name
|
||||
|
||||
def on_register(self):
|
||||
"""
|
||||
Called when the viewset is registered; subclasses can override this to perform additional setup.
|
||||
"""
|
||||
self.register_menu_item()
|
||||
|
||||
def get_urlpatterns(self):
|
||||
"""
|
||||
Returns a set of URL routes to be registered with the Wagtail admin.
|
||||
"""
|
||||
return []
|
||||
|
||||
def get_url_name(self, view_name):
|
||||
"""
|
||||
Returns the namespaced URL name for the given view.
|
||||
"""
|
||||
return self.url_namespace + ":" + view_name
|
||||
|
||||
@cached_property
|
||||
def menu_icon(self):
|
||||
return self.icon
|
||||
|
||||
@cached_property
|
||||
def menu_url(self):
|
||||
return reverse(self.get_url_name(self.get_urlpatterns()[0].name))
|
||||
|
||||
|
||||
class ViewSetGroup(WagtailMenuRegisterableGroup):
|
||||
"""
|
||||
A container for grouping together multiple :class:`ViewSet` instances.
|
||||
Creates a menu item with a submenu for accessing the main URL for each instances.
|
||||
|
||||
For more information on how to use this class, see :ref:`using_base_viewsetgroup`.
|
||||
"""
|
||||
|
||||
def on_register(self):
|
||||
self.register_menu_item()
|
||||
226
env/lib/python3.10/site-packages/wagtail/admin/viewsets/chooser.py
vendored
Normal file
226
env/lib/python3.10/site-packages/wagtail/admin/viewsets/chooser.py
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
from django.db.models import ForeignKey
|
||||
from django.urls import path
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from wagtail.admin.forms.models import register_form_field_override
|
||||
from wagtail.admin.views.generic import chooser as chooser_views
|
||||
from wagtail.admin.widgets.chooser import BaseChooser
|
||||
from wagtail.blocks import ChooserBlock
|
||||
from wagtail.telepath import register as register_telepath_adapter
|
||||
|
||||
from .base import ViewSet
|
||||
|
||||
|
||||
class ChooserViewSet(ViewSet):
|
||||
"""
|
||||
A viewset that creates a chooser modal interface for choosing model instances.
|
||||
"""
|
||||
|
||||
model = None
|
||||
|
||||
icon = "snippet" #: The icon to use in the header of the chooser modal, and on the chooser widget
|
||||
choose_one_text = _(
|
||||
"Choose"
|
||||
) #: Label for the 'choose' button in the chooser widget when choosing an initial item
|
||||
page_title = None #: Title text for the chooser modal (defaults to the same as ``choose_one_text``)`
|
||||
choose_another_text = _(
|
||||
"Choose another"
|
||||
) #: Label for the 'choose' button in the chooser widget, when an item has already been chosen
|
||||
edit_item_text = _("Edit") #: Label for the 'edit' button in the chooser widget
|
||||
|
||||
per_page = ViewSet.UNDEFINED #: Number of results to show per page
|
||||
|
||||
#: A list of URL query parameters that should be passed on unmodified as part of any links or
|
||||
#: form submissions within the chooser modal workflow.
|
||||
preserve_url_parameters = ["multiple"]
|
||||
|
||||
#: A list of URL query parameters that, if present in the url, should be applied as filters to the queryset.
|
||||
#: (These should also be listed in `preserve_url_parameters`.)
|
||||
url_filter_parameters = []
|
||||
|
||||
#: The view class to use for the overall chooser modal; must be a subclass of ``wagtail.admin.views.generic.chooser.ChooseView``.
|
||||
choose_view_class = chooser_views.ChooseView
|
||||
|
||||
#: The view class used to render just the results panel within the chooser modal; must be a subclass of ``wagtail.admin.views.generic.chooser.ChooseResultsView``.
|
||||
choose_results_view_class = chooser_views.ChooseResultsView
|
||||
|
||||
#: The view class used after an item has been chosen; must be a subclass of ``wagtail.admin.views.generic.chooser.ChosenView``.
|
||||
chosen_view_class = chooser_views.ChosenView
|
||||
|
||||
#: The view class used after multiple items have been chosen; must be a subclass of ``wagtail.admin.views.generic.chooser.ChosenMultipleView``.
|
||||
chosen_multiple_view_class = chooser_views.ChosenMultipleView
|
||||
|
||||
#: The view class used to handle submissions of the 'create' form; must be a subclass of ``wagtail.admin.views.generic.chooser.CreateView``.
|
||||
create_view_class = chooser_views.CreateView
|
||||
|
||||
#: The base Widget class that the chooser widget will be derived from.
|
||||
base_widget_class = BaseChooser
|
||||
|
||||
#: The adapter class used to map the widget class to its JavaScript implementation - see :ref:`streamfield_widget_api`.
|
||||
#: Only required if the chooser uses custom JavaScript code.
|
||||
widget_telepath_adapter_class = None
|
||||
|
||||
#: The base ChooserBlock class that the StreamField chooser block will be derived from.
|
||||
base_block_class = ChooserBlock
|
||||
|
||||
#: Defaults to True; if False, the chooser widget will not automatically be registered for use in admin forms.
|
||||
register_widget = True
|
||||
|
||||
#: Form class to use for the form in the "Create" tab of the modal.
|
||||
creation_form_class = None
|
||||
|
||||
#: List of model fields that should be included in the creation form, if creation_form_class is not specified.
|
||||
form_fields = None
|
||||
|
||||
#: List of model fields that should be excluded from the creation form, if creation_form_class.
|
||||
#: If none of ``creation_form_class``, ``form_fields`` or ``exclude_form_fields`` are specified, the "Create" tab will be omitted.
|
||||
exclude_form_fields = None
|
||||
|
||||
search_tab_label = _("Search") #: Label for the 'search' tab in the chooser modal
|
||||
create_action_label = _(
|
||||
"Create"
|
||||
) #: Label for the submit button on the 'create' form
|
||||
create_action_clicked_label = None #: Alternative text to display on the submit button after it has been clicked
|
||||
creation_tab_label = None #: Label for the 'create' tab in the chooser modal (defaults to the same as create_action_label)
|
||||
|
||||
permission_policy = None
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if self.page_title is None:
|
||||
self.page_title = self.choose_one_text
|
||||
|
||||
def get_common_view_kwargs(self, **kwargs):
|
||||
return super().get_common_view_kwargs(
|
||||
**{
|
||||
"model": self.model,
|
||||
"permission_policy": self.permission_policy,
|
||||
"preserve_url_parameters": self.preserve_url_parameters,
|
||||
"url_filter_parameters": self.url_filter_parameters,
|
||||
"create_action_label": self.create_action_label,
|
||||
"create_action_clicked_label": self.create_action_clicked_label,
|
||||
"creation_form_class": self.creation_form_class,
|
||||
"form_fields": self.form_fields,
|
||||
"exclude_form_fields": self.exclude_form_fields,
|
||||
"chosen_url_name": self.get_url_name("chosen"),
|
||||
"chosen_multiple_url_name": self.get_url_name("chosen_multiple"),
|
||||
"results_url_name": self.get_url_name("choose_results"),
|
||||
"create_url_name": self.get_url_name("create"),
|
||||
"per_page": self.per_page,
|
||||
**kwargs,
|
||||
}
|
||||
)
|
||||
|
||||
@property
|
||||
def choose_view(self):
|
||||
view_class = self.inject_view_methods(
|
||||
self.choose_view_class, ["get_object_list"]
|
||||
)
|
||||
|
||||
return self.construct_view(
|
||||
view_class,
|
||||
icon=self.icon,
|
||||
page_title=self.page_title,
|
||||
search_tab_label=self.search_tab_label,
|
||||
creation_tab_label=self.creation_tab_label,
|
||||
)
|
||||
|
||||
@property
|
||||
def choose_results_view(self):
|
||||
view_class = self.inject_view_methods(
|
||||
self.choose_results_view_class, ["get_object_list"]
|
||||
)
|
||||
return self.construct_view(view_class)
|
||||
|
||||
@property
|
||||
def chosen_view(self):
|
||||
return self.construct_view(self.chosen_view_class)
|
||||
|
||||
@property
|
||||
def chosen_multiple_view(self):
|
||||
return self.construct_view(self.chosen_multiple_view_class)
|
||||
|
||||
@property
|
||||
def create_view(self):
|
||||
return self.construct_view(self.create_view_class)
|
||||
|
||||
@cached_property
|
||||
def model_name(self):
|
||||
if isinstance(self.model, str):
|
||||
return self.model.split(".")[-1]
|
||||
else:
|
||||
return self.model.__name__
|
||||
|
||||
@cached_property
|
||||
def widget_class(self):
|
||||
"""
|
||||
Returns the form widget class for this chooser.
|
||||
"""
|
||||
if self.model is None:
|
||||
widget_class_name = "ChooserWidget"
|
||||
else:
|
||||
if isinstance(self.model, str):
|
||||
model_name = self.model.split(".")[-1]
|
||||
else:
|
||||
model_name = self.model.__name__
|
||||
widget_class_name = "%sChooserWidget" % model_name
|
||||
|
||||
return type(
|
||||
widget_class_name,
|
||||
(self.base_widget_class,),
|
||||
{
|
||||
"model": self.model,
|
||||
"choose_one_text": self.choose_one_text,
|
||||
"choose_another_text": self.choose_another_text,
|
||||
"link_to_chosen_text": self.edit_item_text,
|
||||
"chooser_modal_url_name": self.get_url_name("choose"),
|
||||
"icon": self.icon,
|
||||
},
|
||||
)
|
||||
|
||||
def get_block_class(self, name=None, module_path=None):
|
||||
"""
|
||||
Returns a StreamField ChooserBlock class using this chooser.
|
||||
|
||||
:param name: Name to give to the class; defaults to the model name with "ChooserBlock" appended
|
||||
:param module_path: The dotted path of the module where the class can be imported from; used when
|
||||
deconstructing the block definition for migration files.
|
||||
"""
|
||||
meta = type(
|
||||
"Meta",
|
||||
(self.base_block_class._meta_class,),
|
||||
{
|
||||
"icon": self.icon,
|
||||
},
|
||||
)
|
||||
cls = type(
|
||||
name or "%sChooserBlock" % self.model_name,
|
||||
(self.base_block_class,),
|
||||
{
|
||||
"target_model": self.model,
|
||||
"widget": self.widget_class(),
|
||||
"Meta": meta,
|
||||
},
|
||||
)
|
||||
if module_path:
|
||||
cls.__module__ = module_path
|
||||
return cls
|
||||
|
||||
def get_urlpatterns(self):
|
||||
return super().get_urlpatterns() + [
|
||||
path("", self.choose_view, name="choose"),
|
||||
path("results/", self.choose_results_view, name="choose_results"),
|
||||
path("chosen/<str:pk>/", self.chosen_view, name="chosen"),
|
||||
path("chosen-multiple/", self.chosen_multiple_view, name="chosen_multiple"),
|
||||
path("create/", self.create_view, name="create"),
|
||||
]
|
||||
|
||||
def on_register(self):
|
||||
if self.model and self.register_widget:
|
||||
register_form_field_override(
|
||||
ForeignKey, to=self.model, override={"widget": self.widget_class}
|
||||
)
|
||||
if self.widget_telepath_adapter_class:
|
||||
adapter = self.widget_telepath_adapter_class()
|
||||
register_telepath_adapter(adapter, self.widget_class)
|
||||
704
env/lib/python3.10/site-packages/wagtail/admin/viewsets/model.py
vendored
Normal file
704
env/lib/python3.10/site-packages/wagtail/admin/viewsets/model.py
vendored
Normal file
@@ -0,0 +1,704 @@
|
||||
from warnings import warn
|
||||
|
||||
from django.contrib.auth import get_permission_codename
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.forms.models import modelform_factory
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import path
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
from wagtail import hooks
|
||||
from wagtail.admin.admin_url_finder import (
|
||||
ModelAdminURLFinder,
|
||||
register_admin_url_finder,
|
||||
)
|
||||
from wagtail.admin.panels.group import ObjectList
|
||||
from wagtail.admin.views import generic
|
||||
from wagtail.admin.views.generic import history, usage
|
||||
from wagtail.models import ReferenceIndex
|
||||
from wagtail.permissions import ModelPermissionPolicy
|
||||
from wagtail.utils.deprecation import RemovedInWagtail70Warning
|
||||
|
||||
from .base import ViewSet, ViewSetGroup
|
||||
|
||||
|
||||
class ModelViewSet(ViewSet):
|
||||
"""
|
||||
A viewset to allow listing, creating, editing and deleting model instances.
|
||||
|
||||
All attributes and methods from :class:`~wagtail.admin.viewsets.base.ViewSet`
|
||||
are available.
|
||||
|
||||
For more information on how to use this class, see :ref:`generic_views`.
|
||||
"""
|
||||
|
||||
#: Register the model to the reference index to track its usage.
|
||||
#: For more details, see :ref:`managing_the_reference_index`.
|
||||
add_to_reference_index = True
|
||||
|
||||
#: The view class to use for the index view; must be a subclass of ``wagtail.admin.views.generic.IndexView``.
|
||||
index_view_class = generic.IndexView
|
||||
|
||||
#: The view class to use for the create view; must be a subclass of ``wagtail.admin.views.generic.CreateView``.
|
||||
add_view_class = generic.CreateView
|
||||
|
||||
#: The view class to use for the edit view; must be a subclass of ``wagtail.admin.views.generic.EditView``.
|
||||
edit_view_class = generic.EditView
|
||||
|
||||
#: The view class to use for the delete view; must be a subclass of ``wagtail.admin.views.generic.DeleteView``.
|
||||
delete_view_class = generic.DeleteView
|
||||
|
||||
#: The view class to use for the history view; must be a subclass of ``wagtail.admin.views.generic.history.HistoryView``.
|
||||
history_view_class = history.HistoryView
|
||||
|
||||
#: The view class to use for the usage view; must be a subclass of ``wagtail.admin.views.generic.usage.UsageView``.
|
||||
usage_view_class = usage.UsageView
|
||||
|
||||
#: The view class to use for the copy view; must be a subclass of ``wagtail.admin.views.generic.CopyView``.
|
||||
copy_view_class = generic.CopyView
|
||||
|
||||
#: The view class to use for the inspect view; must be a subclass of ``wagtail.admin.views.generic.InspectView``.
|
||||
inspect_view_class = generic.InspectView
|
||||
|
||||
# Breadcrumbs can be turned off until we have a design that can be consistently applied
|
||||
_show_breadcrumbs = True
|
||||
|
||||
#: The prefix of template names to look for when rendering the admin views.
|
||||
template_prefix = ""
|
||||
|
||||
#: The number of items to display per page in the index view. Defaults to 20.
|
||||
list_per_page = 20
|
||||
|
||||
#: The default ordering to use for the index view.
|
||||
#: Can be a string or a list/tuple in the same format as Django's
|
||||
#: :attr:`~django.db.models.Options.ordering`.
|
||||
ordering = None
|
||||
|
||||
#: Whether to enable the inspect view. Defaults to ``False``.
|
||||
inspect_view_enabled = False
|
||||
|
||||
#: The model fields or attributes to display in the inspect view.
|
||||
#:
|
||||
#: If the field has a corresponding :meth:`~django.db.models.Model.get_FOO_display`
|
||||
#: method on the model, the method's return value will be used instead.
|
||||
#:
|
||||
#: If you have ``wagtail.images`` installed, and the field's value is an instance of
|
||||
#: ``wagtail.images.models.AbstractImage``, a thumbnail of that image will be rendered.
|
||||
#:
|
||||
#: If you have ``wagtail.documents`` installed, and the field's value is an instance of
|
||||
#: ``wagtail.docs.models.AbstractDocument``, a link to that document will be rendered,
|
||||
#: along with the document title, file extension and size.
|
||||
inspect_view_fields = []
|
||||
|
||||
#: The fields to exclude from the inspect view.
|
||||
inspect_view_fields_exclude = []
|
||||
|
||||
#: Whether to enable the copy view. Defaults to ``True``.
|
||||
copy_view_enabled = True
|
||||
|
||||
def __init__(self, name=None, **kwargs):
|
||||
super().__init__(name=name, **kwargs)
|
||||
if not self.model:
|
||||
raise ImproperlyConfigured(
|
||||
"ModelViewSet %r must define a `model` attribute or pass a `model` argument"
|
||||
% self
|
||||
)
|
||||
|
||||
self.model_opts = self.model._meta
|
||||
self.app_label = self.model_opts.app_label
|
||||
self.model_name = self.model_opts.model_name
|
||||
|
||||
@property
|
||||
def permission_policy(self):
|
||||
return ModelPermissionPolicy(self.model)
|
||||
|
||||
@cached_property
|
||||
def name(self):
|
||||
"""
|
||||
Viewset name, to use as the URL prefix and namespace.
|
||||
Defaults to the :attr:`~django.db.models.Options.model_name`.
|
||||
"""
|
||||
return self.model_name
|
||||
|
||||
def get_common_view_kwargs(self, **kwargs):
|
||||
view_kwargs = super().get_common_view_kwargs(
|
||||
**{
|
||||
"model": self.model,
|
||||
"permission_policy": self.permission_policy,
|
||||
"index_url_name": self.get_url_name("index"),
|
||||
"index_results_url_name": self.get_url_name("index_results"),
|
||||
"history_url_name": self.get_url_name("history"),
|
||||
"usage_url_name": self.get_url_name("usage"),
|
||||
"add_url_name": self.get_url_name("add"),
|
||||
"edit_url_name": self.get_url_name("edit"),
|
||||
"delete_url_name": self.get_url_name("delete"),
|
||||
"header_icon": self.icon,
|
||||
"_show_breadcrumbs": self._show_breadcrumbs,
|
||||
**kwargs,
|
||||
}
|
||||
)
|
||||
if self.copy_view_enabled:
|
||||
view_kwargs["copy_url_name"] = self.get_url_name("copy")
|
||||
if self.inspect_view_enabled:
|
||||
view_kwargs["inspect_url_name"] = self.get_url_name("inspect")
|
||||
return view_kwargs
|
||||
|
||||
def get_index_view_kwargs(self, **kwargs):
|
||||
view_kwargs = {
|
||||
"template_name": self.index_template_name,
|
||||
"results_template_name": self.index_results_template_name,
|
||||
"list_display": self.list_display,
|
||||
"list_filter": self.list_filter,
|
||||
"list_export": self.list_export,
|
||||
"export_headings": self.export_headings,
|
||||
"export_filename": self.export_filename,
|
||||
"filterset_class": self.filterset_class,
|
||||
"search_fields": self.search_fields,
|
||||
"search_backend_name": self.search_backend_name,
|
||||
"paginate_by": self.list_per_page,
|
||||
**kwargs,
|
||||
}
|
||||
if self.ordering:
|
||||
view_kwargs["default_ordering"] = self.ordering
|
||||
return view_kwargs
|
||||
|
||||
def get_add_view_kwargs(self, **kwargs):
|
||||
return {
|
||||
"panel": self._edit_handler,
|
||||
"form_class": self.get_form_class(),
|
||||
"template_name": self.create_template_name,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
def get_edit_view_kwargs(self, **kwargs):
|
||||
return {
|
||||
"panel": self._edit_handler,
|
||||
"form_class": self.get_form_class(for_update=True),
|
||||
"template_name": self.edit_template_name,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
def get_delete_view_kwargs(self, **kwargs):
|
||||
return {
|
||||
"template_name": self.delete_template_name,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
def get_history_view_kwargs(self, **kwargs):
|
||||
return {
|
||||
"template_name": self.history_template_name,
|
||||
"history_results_url_name": self.get_url_name("history_results"),
|
||||
"header_icon": "history",
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
def get_usage_view_kwargs(self, **kwargs):
|
||||
return {
|
||||
"template_name": self.get_templates(
|
||||
"usage", fallback=self.usage_view_class.template_name
|
||||
),
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
def get_inspect_view_kwargs(self, **kwargs):
|
||||
return {
|
||||
"template_name": self.inspect_template_name,
|
||||
"fields": self.inspect_view_fields,
|
||||
"fields_exclude": self.inspect_view_fields_exclude,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
def get_copy_view_kwargs(self, **kwargs):
|
||||
return self.get_add_view_kwargs(**kwargs)
|
||||
|
||||
@property
|
||||
def index_view(self):
|
||||
return self.construct_view(
|
||||
self.index_view_class, **self.get_index_view_kwargs()
|
||||
)
|
||||
|
||||
@property
|
||||
def index_results_view(self):
|
||||
return self.construct_view(
|
||||
self.index_view_class, **self.get_index_view_kwargs(), results_only=True
|
||||
)
|
||||
|
||||
@property
|
||||
def add_view(self):
|
||||
return self.construct_view(self.add_view_class, **self.get_add_view_kwargs())
|
||||
|
||||
@property
|
||||
def edit_view(self):
|
||||
return self.construct_view(self.edit_view_class, **self.get_edit_view_kwargs())
|
||||
|
||||
@property
|
||||
def delete_view(self):
|
||||
return self.construct_view(
|
||||
self.delete_view_class, **self.get_delete_view_kwargs()
|
||||
)
|
||||
|
||||
@property
|
||||
def redirect_to_edit_view(self):
|
||||
def redirect_to_edit(request, pk):
|
||||
warn(
|
||||
(
|
||||
"%s's `/<pk>/` edit view URL pattern has been "
|
||||
"deprecated in favour of /edit/<pk>/."
|
||||
)
|
||||
% (self.__class__.__name__),
|
||||
category=RemovedInWagtail70Warning,
|
||||
)
|
||||
return redirect(self.get_url_name("edit"), pk, permanent=True)
|
||||
|
||||
return redirect_to_edit
|
||||
|
||||
@property
|
||||
def redirect_to_delete_view(self):
|
||||
def redirect_to_delete(request, pk):
|
||||
warn(
|
||||
(
|
||||
"%s's `/<pk>/delete/` delete view URL pattern has been "
|
||||
"deprecated in favour of /delete/<pk>/."
|
||||
)
|
||||
% (self.__class__.__name__),
|
||||
category=RemovedInWagtail70Warning,
|
||||
)
|
||||
return redirect(self.get_url_name("delete"), pk, permanent=True)
|
||||
|
||||
return redirect_to_delete
|
||||
|
||||
@property
|
||||
def history_view(self):
|
||||
return self.construct_view(
|
||||
self.history_view_class, **self.get_history_view_kwargs()
|
||||
)
|
||||
|
||||
@property
|
||||
def history_results_view(self):
|
||||
return self.construct_view(
|
||||
self.history_view_class, **self.get_history_view_kwargs(), results_only=True
|
||||
)
|
||||
|
||||
@property
|
||||
def usage_view(self):
|
||||
return self.construct_view(
|
||||
self.usage_view_class, **self.get_usage_view_kwargs()
|
||||
)
|
||||
|
||||
@property
|
||||
def inspect_view(self):
|
||||
return self.construct_view(
|
||||
self.inspect_view_class, **self.get_inspect_view_kwargs()
|
||||
)
|
||||
|
||||
@property
|
||||
def copy_view(self):
|
||||
return self.construct_view(self.copy_view_class, **self.get_copy_view_kwargs())
|
||||
|
||||
def get_templates(self, name="index", fallback=""):
|
||||
"""
|
||||
Utility function that provides a list of templates to try for a given
|
||||
view, when the template isn't overridden by one of the template
|
||||
attributes on the class.
|
||||
"""
|
||||
if not self.template_prefix:
|
||||
return [fallback]
|
||||
templates = [
|
||||
f"{self.template_prefix}{self.app_label}/{self.model_name}/{name}.html",
|
||||
f"{self.template_prefix}{self.app_label}/{name}.html",
|
||||
f"{self.template_prefix}{name}.html",
|
||||
]
|
||||
if fallback:
|
||||
templates.append(fallback)
|
||||
return templates
|
||||
|
||||
@cached_property
|
||||
def index_template_name(self):
|
||||
"""
|
||||
A template to be used when rendering ``index_view``.
|
||||
|
||||
Default: if :attr:`template_prefix` is specified, an ``index.html``
|
||||
template in the prefix directory and its ``{app_label}/{model_name}/``
|
||||
or ``{app_label}/`` subdirectories will be used. Otherwise, the
|
||||
``index_view_class.template_name`` will be used.
|
||||
"""
|
||||
return self.get_templates(
|
||||
"index",
|
||||
fallback=self.index_view_class.template_name,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def index_results_template_name(self):
|
||||
"""
|
||||
A template to be used when rendering ``index_results_view``.
|
||||
|
||||
Default: if :attr:`template_prefix` is specified, a ``index_results.html``
|
||||
template in the prefix directory and its ``{app_label}/{model_name}/``
|
||||
or ``{app_label}/`` subdirectories will be used. Otherwise, the
|
||||
``index_view_class.results_template_name`` will be used.
|
||||
"""
|
||||
return self.get_templates(
|
||||
"index_results",
|
||||
fallback=self.index_view_class.results_template_name,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def create_template_name(self):
|
||||
"""
|
||||
A template to be used when rendering ``add_view``.
|
||||
|
||||
Default: if :attr:`template_prefix` is specified, a ``create.html``
|
||||
template in the prefix directory and its ``{app_label}/{model_name}/``
|
||||
or ``{app_label}/`` subdirectories will be used. Otherwise, the
|
||||
``add_view_class.template_name`` will be used.
|
||||
"""
|
||||
return self.get_templates(
|
||||
"create",
|
||||
fallback=self.add_view_class.template_name,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def edit_template_name(self):
|
||||
"""
|
||||
A template to be used when rendering ``edit_view``.
|
||||
|
||||
Default: if :attr:`template_prefix` is specified, an ``edit.html``
|
||||
template in the prefix directory and its ``{app_label}/{model_name}/``
|
||||
or ``{app_label}/`` subdirectories will be used. Otherwise, the
|
||||
``edit_view_class.template_name`` will be used.
|
||||
"""
|
||||
return self.get_templates(
|
||||
"edit",
|
||||
fallback=self.edit_view_class.template_name,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def delete_template_name(self):
|
||||
"""
|
||||
A template to be used when rendering ``delete_view``.
|
||||
|
||||
Default: if :attr:`template_prefix` is specified, a ``confirm_delete.html``
|
||||
template in the prefix directory and its ``{app_label}/{model_name}/``
|
||||
or ``{app_label}/`` subdirectories will be used. Otherwise, the
|
||||
``delete_view_class.template_name`` will be used.
|
||||
"""
|
||||
return self.get_templates(
|
||||
"confirm_delete",
|
||||
fallback=self.delete_view_class.template_name,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def history_template_name(self):
|
||||
"""
|
||||
A template to be used when rendering ``history_view``.
|
||||
|
||||
Default: if :attr:`template_prefix` is specified, a ``history.html``
|
||||
template in the prefix directory and its ``{app_label}/{model_name}/``
|
||||
or ``{app_label}/`` subdirectories will be used. Otherwise, the
|
||||
``history_view_class.template_name`` will be used.
|
||||
"""
|
||||
return self.get_templates(
|
||||
"history",
|
||||
fallback=self.history_view_class.template_name,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def inspect_template_name(self):
|
||||
"""
|
||||
A template to be used when rendering ``inspect_view``.
|
||||
|
||||
Default: if :attr:`template_prefix` is specified, an ``inspect.html``
|
||||
template in the prefix directory and its ``{app_label}/{model_name}/``
|
||||
or ``{app_label}/`` subdirectories will be used. Otherwise, the
|
||||
``inspect_view_class.template_name`` will be used.
|
||||
"""
|
||||
return self.get_templates(
|
||||
"inspect",
|
||||
fallback=self.inspect_view_class.template_name,
|
||||
)
|
||||
|
||||
@cached_property
|
||||
def list_display(self):
|
||||
"""
|
||||
A list or tuple, where each item is either:
|
||||
|
||||
- The name of a field on the model;
|
||||
- The name of a callable or property on the model that accepts a single
|
||||
parameter for the model instance; or
|
||||
- An instance of the ``wagtail.admin.ui.tables.Column`` class.
|
||||
|
||||
If the name refers to a database field, the ability to sort the listing
|
||||
by the database column will be offerred and the field's verbose name
|
||||
will be used as the column header.
|
||||
|
||||
If the name refers to a callable or property, an ``admin_order_field``
|
||||
attribute can be defined on it to point to the database column for
|
||||
sorting. A ``short_description`` attribute can also be defined on the
|
||||
callable or property to be used as the column header.
|
||||
|
||||
This list will be passed to the ``list_display`` attribute of the index
|
||||
view. If left unset, the ``list_display`` attribute of the index view
|
||||
will be used instead, which by default is defined as
|
||||
``["__str__", wagtail.admin.ui.tables.UpdatedAtColumn()]``.
|
||||
"""
|
||||
return self.index_view_class.list_display
|
||||
|
||||
@cached_property
|
||||
def list_filter(self):
|
||||
"""
|
||||
A list or tuple, where each item is the name of model fields of type
|
||||
``BooleanField``, ``CharField``, ``DateField``, ``DateTimeField``,
|
||||
``IntegerField`` or ``ForeignKey``.
|
||||
Alternatively, it can also be a dictionary that maps a field name to a
|
||||
list of lookup expressions.
|
||||
This will be passed as django-filter's ``FilterSet.Meta.fields``
|
||||
attribute. See
|
||||
`its documentation <https://django-filter.readthedocs.io/en/stable/guide/usage.html#generating-filters-with-meta-fields>`_
|
||||
for more details.
|
||||
If ``filterset_class`` is set, this attribute will be ignored.
|
||||
"""
|
||||
return self.index_view_class.list_filter
|
||||
|
||||
@cached_property
|
||||
def filterset_class(self):
|
||||
"""
|
||||
A subclass of ``wagtail.admin.filters.WagtailFilterSet``, which is a
|
||||
subclass of `django_filters.FilterSet <https://django-filter.readthedocs.io/en/stable/ref/filterset.html>`_.
|
||||
This will be passed to the ``filterset_class`` attribute of the index view.
|
||||
"""
|
||||
return self.index_view_class.filterset_class
|
||||
|
||||
@cached_property
|
||||
def search_fields(self):
|
||||
"""
|
||||
The fields to use for the search in the index view.
|
||||
If set to ``None`` and :attr:`search_backend_name` is set to use a Wagtail search backend,
|
||||
the ``search_fields`` attribute of the model will be used instead.
|
||||
"""
|
||||
return self.index_view_class.search_fields
|
||||
|
||||
@cached_property
|
||||
def search_backend_name(self):
|
||||
"""
|
||||
The name of the Wagtail search backend to use for the search in the index view.
|
||||
If set to a falsy value, the search will fall back to use Django's QuerySet API.
|
||||
"""
|
||||
return self.index_view_class.search_backend_name
|
||||
|
||||
@cached_property
|
||||
def list_export(self):
|
||||
"""
|
||||
A list or tuple, where each item is the name of a field, an attribute,
|
||||
or a single-argument callable on the model to be exported.
|
||||
"""
|
||||
return self.index_view_class.list_export
|
||||
|
||||
@cached_property
|
||||
def export_headings(self):
|
||||
"""
|
||||
A dictionary of export column heading overrides in the format
|
||||
``{field_name: heading}``.
|
||||
"""
|
||||
return self.index_view_class.export_headings
|
||||
|
||||
@cached_property
|
||||
def export_filename(self):
|
||||
"""
|
||||
The base file name for the exported listing, without extensions.
|
||||
If unset, the model's :attr:`~django.db.models.Options.db_table` will be
|
||||
used instead.
|
||||
"""
|
||||
return self.model._meta.db_table
|
||||
|
||||
@cached_property
|
||||
def menu_label(self):
|
||||
return self.model_opts.verbose_name_plural.title()
|
||||
|
||||
@cached_property
|
||||
def menu_item_class(self):
|
||||
from wagtail.admin.menu import MenuItem
|
||||
|
||||
def is_shown(_self, request):
|
||||
return self.permission_policy.user_has_any_permission(
|
||||
request.user, self.index_view_class.any_permission_required
|
||||
)
|
||||
|
||||
return type(
|
||||
f"{self.model.__name__}MenuItem",
|
||||
(MenuItem,),
|
||||
{"is_shown": is_shown},
|
||||
)
|
||||
|
||||
def formfield_for_dbfield(self, db_field, **kwargs):
|
||||
return db_field.formfield(**kwargs)
|
||||
|
||||
def get_form_class(self, for_update=False):
|
||||
"""
|
||||
Returns the form class to use for the create / edit forms.
|
||||
"""
|
||||
# If an edit handler is defined, use it to construct the form class.
|
||||
if self._edit_handler:
|
||||
return self._edit_handler.get_form_class()
|
||||
|
||||
# Otherwise, use Django's modelform_factory.
|
||||
fields = self.get_form_fields()
|
||||
exclude = self.get_exclude_form_fields()
|
||||
|
||||
if fields is None and exclude is None:
|
||||
raise ImproperlyConfigured(
|
||||
"Subclasses of ModelViewSet must specify 'get_form_class', 'form_fields' "
|
||||
"or 'exclude_form_fields'."
|
||||
)
|
||||
|
||||
return modelform_factory(
|
||||
self.model,
|
||||
formfield_callback=self.formfield_for_dbfield,
|
||||
fields=fields,
|
||||
exclude=exclude,
|
||||
)
|
||||
|
||||
def get_form_fields(self):
|
||||
"""
|
||||
Returns a list or tuple of field names to be included in the create / edit forms.
|
||||
"""
|
||||
return getattr(self, "form_fields", None)
|
||||
|
||||
def get_exclude_form_fields(self):
|
||||
"""
|
||||
Returns a list or tuple of field names to be excluded from the create / edit forms.
|
||||
"""
|
||||
return getattr(self, "exclude_form_fields", None)
|
||||
|
||||
def get_edit_handler(self):
|
||||
"""
|
||||
Returns the appropriate edit handler for this ``ModelViewSet`` class.
|
||||
It can be defined either on the model itself or on the ``ModelViewSet``,
|
||||
as the ``edit_handler`` or ``panels`` properties. If none of these are
|
||||
defined, it will return ``None`` and the form will be constructed as
|
||||
a Django form using :meth:`get_form_class` (without using
|
||||
:ref:`forms_panels_overview`).
|
||||
"""
|
||||
if hasattr(self, "edit_handler"):
|
||||
edit_handler = self.edit_handler
|
||||
elif hasattr(self, "panels"):
|
||||
panels = self.panels
|
||||
edit_handler = ObjectList(panels)
|
||||
elif hasattr(self.model, "edit_handler"):
|
||||
edit_handler = self.model.edit_handler
|
||||
elif hasattr(self.model, "panels"):
|
||||
panels = self.model.panels
|
||||
edit_handler = ObjectList(panels)
|
||||
else:
|
||||
return None
|
||||
return edit_handler.bind_to_model(self.model)
|
||||
|
||||
@cached_property
|
||||
def _edit_handler(self):
|
||||
"""
|
||||
An edit handler that has been bound to the model class,
|
||||
to be used across views.
|
||||
"""
|
||||
return self.get_edit_handler()
|
||||
|
||||
@property
|
||||
def url_finder_class(self):
|
||||
return type(
|
||||
"_ModelAdminURLFinder",
|
||||
(ModelAdminURLFinder,),
|
||||
{
|
||||
"permission_policy": self.permission_policy,
|
||||
"edit_url_name": self.get_url_name("edit"),
|
||||
},
|
||||
)
|
||||
|
||||
def register_admin_url_finder(self):
|
||||
register_admin_url_finder(self.model, self.url_finder_class)
|
||||
|
||||
def register_reference_index(self):
|
||||
if self.add_to_reference_index:
|
||||
ReferenceIndex.register_model(self.model)
|
||||
|
||||
def get_permissions_to_register(self):
|
||||
"""
|
||||
Returns a queryset of :class:`~django.contrib.auth.models.Permission`
|
||||
objects to be registered with the :ref:`register_permissions` hook. By
|
||||
default, it returns all permissions for the model if
|
||||
:attr:`inspect_view_enabled` is set to ``True``. Otherwise, the "view"
|
||||
permission is excluded.
|
||||
"""
|
||||
content_type = ContentType.objects.get_for_model(self.model)
|
||||
permissions = Permission.objects.filter(content_type=content_type)
|
||||
# Only register the "view" permission if the inspect view is enabled
|
||||
if not self.inspect_view_enabled:
|
||||
permissions = permissions.exclude(
|
||||
codename=get_permission_codename("view", self.model_opts)
|
||||
)
|
||||
return permissions
|
||||
|
||||
def register_permissions(self):
|
||||
hooks.register("register_permissions", self.get_permissions_to_register)
|
||||
|
||||
def get_urlpatterns(self):
|
||||
urlpatterns = [
|
||||
path("", self.index_view, name="index"),
|
||||
path("results/", self.index_results_view, name="index_results"),
|
||||
path("new/", self.add_view, name="add"),
|
||||
path("edit/<str:pk>/", self.edit_view, name="edit"),
|
||||
path("delete/<str:pk>/", self.delete_view, name="delete"),
|
||||
path("history/<str:pk>/", self.history_view, name="history"),
|
||||
path(
|
||||
"history-results/<str:pk>/",
|
||||
self.history_results_view,
|
||||
name="history_results",
|
||||
),
|
||||
path("usage/<str:pk>/", self.usage_view, name="usage"),
|
||||
]
|
||||
|
||||
if self.inspect_view_enabled:
|
||||
urlpatterns.append(
|
||||
path("inspect/<str:pk>/", self.inspect_view, name="inspect")
|
||||
)
|
||||
|
||||
if self.copy_view_enabled:
|
||||
urlpatterns.append(path("copy/<str:pk>/", self.copy_view, name="copy"))
|
||||
|
||||
# RemovedInWagtail70Warning: Remove legacy URL patterns
|
||||
urlpatterns += self._legacy_urlpatterns
|
||||
|
||||
return urlpatterns
|
||||
|
||||
@cached_property
|
||||
def _legacy_urlpatterns(self):
|
||||
# RemovedInWagtail70Warning: Remove legacy URL patterns
|
||||
return [
|
||||
path("<str:pk>/", self.redirect_to_edit_view),
|
||||
path("<str:pk>/delete/", self.redirect_to_delete_view),
|
||||
]
|
||||
|
||||
def on_register(self):
|
||||
super().on_register()
|
||||
self.register_admin_url_finder()
|
||||
self.register_reference_index()
|
||||
self.register_permissions()
|
||||
|
||||
|
||||
class ModelViewSetGroup(ViewSetGroup):
|
||||
"""
|
||||
A container for grouping together multiple
|
||||
:class:`~wagtail.admin.viewsets.model.ModelViewSet` instances.
|
||||
|
||||
All attributes and methods from
|
||||
:class:`~wagtail.admin.viewsets.base.ViewSetGroup` are available.
|
||||
"""
|
||||
|
||||
def get_app_label_from_subitems(self):
|
||||
for instance in self.registerables:
|
||||
if app_label := getattr(instance, "app_label", ""):
|
||||
return app_label.title()
|
||||
return ""
|
||||
|
||||
@cached_property
|
||||
def menu_label(self):
|
||||
return self.get_app_label_from_subitems()
|
||||
77
env/lib/python3.10/site-packages/wagtail/admin/viewsets/pages.py
vendored
Normal file
77
env/lib/python3.10/site-packages/wagtail/admin/viewsets/pages.py
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
from django.urls import path
|
||||
|
||||
from wagtail.admin.views.pages.choose_parent import ChooseParentView
|
||||
from wagtail.admin.views.pages.listing import IndexView
|
||||
from wagtail.models import Page
|
||||
|
||||
from .base import ViewSet
|
||||
|
||||
|
||||
class PageListingViewSet(ViewSet):
|
||||
"""
|
||||
A viewset to present a flat listing of all pages of a specific type.
|
||||
All attributes and methods from :class:`~wagtail.admin.viewsets.base.ViewSet`
|
||||
are available.
|
||||
For more information on how to use this class, see :ref:`custom_page_listings`.
|
||||
"""
|
||||
|
||||
#: The view class to use for the index view; must be a subclass of ``wagtail.admin.views.pages.listing.IndexView``.
|
||||
index_view_class = IndexView
|
||||
#: The view class to use for choosing the parent page when creating a new page of this page type.
|
||||
choose_parent_view_class = ChooseParentView
|
||||
#: Required; the page model class that this viewset will work with.
|
||||
model = Page
|
||||
#: A list of ``wagtail.admin.ui.tables.Column`` instances for the columns in the listing.
|
||||
columns = IndexView.columns
|
||||
#: A subclass of ``wagtail.admin.filters.WagtailFilterSet``, which is a
|
||||
#: subclass of `django_filters.FilterSet <https://django-filter.readthedocs.io/en/stable/ref/filterset.html>`_.
|
||||
#: This will be passed to the ``filterset_class`` attribute of the index view.
|
||||
filterset_class = IndexView.filterset_class
|
||||
|
||||
def get_common_view_kwargs(self, **kwargs):
|
||||
return super().get_common_view_kwargs(
|
||||
**{
|
||||
"_show_breadcrumbs": True,
|
||||
"header_icon": self.icon,
|
||||
"model": self.model,
|
||||
"index_url_name": self.get_url_name("index"),
|
||||
"add_url_name": self.get_url_name("choose_parent"),
|
||||
**kwargs,
|
||||
}
|
||||
)
|
||||
|
||||
def get_index_view_kwargs(self, **kwargs):
|
||||
return {
|
||||
"index_results_url_name": self.get_url_name("index_results"),
|
||||
"columns": self.columns,
|
||||
"filterset_class": self.filterset_class,
|
||||
**kwargs,
|
||||
}
|
||||
|
||||
def get_choose_parent_view_kwargs(self, **kwargs):
|
||||
return kwargs
|
||||
|
||||
@property
|
||||
def index_view(self):
|
||||
return self.construct_view(
|
||||
self.index_view_class, **self.get_index_view_kwargs()
|
||||
)
|
||||
|
||||
@property
|
||||
def index_results_view(self):
|
||||
return self.construct_view(
|
||||
self.index_view_class, **self.get_index_view_kwargs(), results_only=True
|
||||
)
|
||||
|
||||
@property
|
||||
def choose_parent_view(self):
|
||||
return self.construct_view(
|
||||
self.choose_parent_view_class, **self.get_choose_parent_view_kwargs()
|
||||
)
|
||||
|
||||
def get_urlpatterns(self):
|
||||
return [
|
||||
path("", self.index_view, name="index"),
|
||||
path("results/", self.index_results_view, name="index_results"),
|
||||
path("choose_parent/", self.choose_parent_view, name="choose_parent"),
|
||||
]
|
||||
Reference in New Issue
Block a user