Newer
Older
from django.forms.utils import pretty_name
from django.urls import reverse
from django.utils.html import format_html, mark_safe
from django.utils.translation import ugettext_lazy as _
from wagtail.wagtailcore.models import Page
from wagtail.wagtailadmin.edit_handlers import BaseFieldPanel, EditHandler, FieldPanel
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class BaseReadOnlyPanel(EditHandler):
def render(self):
value = getattr(self.instance, self.attr)
if callable(value):
value = value()
return format_html('<div style="padding-top: 1.2em;">{}</div>', value)
def render_as_object(self):
return format_html(
'<fieldset><legend>{}</legend>'
'<ul class="fields"><li><div class="field">{}</div></li></ul>'
'</fieldset>',
self.heading, self.render())
def render_as_field(self):
return format_html(
'<div class="field">'
'<label>{}{}</label>'
'<div class="field-content">{}</div>'
'</div>',
self.heading, _(':'), self.render())
class ReadOnlyPanel:
def __init__(self, attr, heading=None, classname=''):
self.attr = attr
self.heading = pretty_name(self.attr) if heading is None else heading
self.classname = classname
def bind_to_model(self, model):
return type(str(_('ReadOnlyPanel')), (BaseReadOnlyPanel,),
{'attr': self.attr, 'heading': self.heading,
'classname': self.classname})
def reverse_edit(obj):
if isinstance(obj, Page):
return reverse('wagtailadmin_pages:edit', args=(obj.id,))
url_name = f'{obj._meta.app_label}_{obj._meta.model_name}_modeladmin_edit'
return reverse(url_name, args=(obj.id,))
class BaseReadOnlyInlinePanel(BaseReadOnlyPanel):
def render(self):
values = getattr(self.instance, self.attr).all()
return mark_safe(
''.join(
'<div style="padding-top: 1.2em;">'
f'{value}<br><a class="button button-small" href="{reverse_edit(value.form)}">Edit</a></div>'
for value in values
)
)
class ReadOnlyInlinePanel:
def __init__(self, attr, heading=None, classname=''):
self.attr = attr
self.heading = pretty_name(self.attr) if heading is None else heading
self.classname = classname
def bind_to_model(self, model):
return type(str(_('ReadOnlyPanel')), (BaseReadOnlyInlinePanel,),
{'attr': self.attr, 'heading': self.heading,
'classname': self.classname})
class BaseFilteredFieldPanel(BaseFieldPanel):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
target_model = self.bound_field.field.queryset.model
self.bound_field.field.queryset = target_model.objects.filter(**self.filter_query)
class FilteredFieldPanel(FieldPanel):
def __init__(self, *args, filter_query=dict(), **kwargs):
self.filter_query = filter_query
super().__init__(*args, **kwargs)
def bind_to_model(self, model):
base = {
'model': model,
'field_name': self.field_name,
'classname': self.classname,
'filter_query': self.filter_query
}
if self.widget:
base['widget'] = self.widget
return type(str('_BaseFilteredFieldPanel'), (BaseFilteredFieldPanel,), base)