Aug 2022 - Wagtail 2.15.5 - display Wagtail hierarchical collection

from wagtail.admin.templatetags.wagtailadmin_tags import format_collection
class Meeting(models.Model):
COLLECTION_CHOICES = []
for c in Collection.objects.all():
COLLECTION_CHOICES.append((c.id, format_collection(c)))
title = models.CharField(max_length=100)
collection = models.ForeignKey(Collection, on_delete=models.PROTECT, help_text="Choose the 'Collection' folder for the meeting's related documents", choices=COLLECTION_CHOICES)
Edit: If you add a new collection to collections and go back the this Meeting model the new collection will not be in the list. As the COLLECTION_CHOICES is only created once for optimization. If you want a dynamic collection choice you need to make a custom form on top of your model e.g.
from wagtail.admin.forms import WagtailAdminModelForm
class MeetingAdminForm(WagtailAdminModelForm):
# This below field will be automatically added to the Meeting panel fields
meeting_collection = forms.ChoiceField()
def __init__(self, *args, **kwargs):
super(MeetingAdminForm, self).__init__(*args, **kwargs)
self.fields['meeting_collection'] = forms.ChoiceField(
initial=self.instance.collection_id,
choices=[(c.id, format_collection(c)) for c in Collection.objects.all()]
)
def save(self, commit=True):
instance = super().save(commit=False)
instance.collection_id = self.cleaned_data['meeting_collection']
if commit:
instance.save()
return instance
class Meeting(models.Model):
base_form_class = MeetingAdminForm
class Meta:
""" Meta options """
ordering = ['title']
title = models.CharField(max_length=100)
meeting_datetime = models.DateTimeField()
location = models.TextField(null=True)
collection = models.ForeignKey(Collection, on_delete=models.PROTECT, help_text="Choose the 'Collection' folder for the meeting's agenda, minutes and related documents")
committee = models.ForeignKey(Committee, on_delete=models.CASCADE)
panels = [
FieldPanel('title'),
FieldPanel('meeting_datetime'),
FieldPanel('location'),
FieldPanel('meeting_collection'),
FieldPanel('committee'),
]