Reputation: 320
I am trying to set make a footer for a Wagtail site that is included on every page, but I want to include a list of links (phone, email, social media). If I try the code below without the panel = [...]
I can see it sort of works, but I am unable to add any items:
from wagtail.contrib.settings.models import BaseSetting, register_setting
from django import forms
class ContactInfo(models.Model):
CONTACT_CHOICES = (
('fas fa-phone', 'Phone'),
('fas fa-envelope', 'Email'),
('fab fa-facebook-f', 'Facebook'),
('fa-instagram', 'Instagram'),
('fab fa-linkedin', 'LinkedIn'),
('fab fa-twitter', 'Twitter'),
('fab fa-pinterest', 'Pinterest'),
('fab fa-github', 'GitHub'),
('fab fa-gitlab', 'GitLab'),
)
contact_type = models.CharField(choices=CONTACT_CHOICES, max_length=50)
contact_info = models.CharField(max_length=50)
info_prefix = models.CharField(max_length=10, editable=False)
def save(self, *args, **kwargs):
if self.contact_type == 'Phone':
self.info_prefix = 'tel:'
elif self.contact_type == 'Email':
self.info_prefix = 'mailto:'
else:
self.info_prefix = ''
@register_setting
class Contact(BaseSetting):
contact = models.ManyToManyField(ContactInfo)
panels = [
FieldPanel('contact', widget=forms.CheckboxSelectMultiple)
]
Is there a to add items to the M2M field? Is there a way to make lists of items in the Wagtail settings? Is there an easier way to make a footer that automatically is rendered on every page?
Upvotes: 1
Views: 3513
Reputation: 25292
Each ContactInfo
item (presumably) belongs to a single Contact
, so this is a one-to-many relation rather than many-to-many. (A many-to-many relation in this case would mean that you have a shared pool of ContactInfo
items previously defined through some other view, and you're selecting which ones to attach to the current Contact
.)
In Wagtail, this would be defined using a ParentalKey
on ContactInfo
to point to the corresponding Contact
, and rendered with an InlinePanel
. (See the gallery image example from the Wagtail tutorial for an example.)
from django.db import models
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel
from wagtail.core.models import Orderable
from wagtail.contrib.settings.models import BaseSetting, register_setting
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
class ContactInfo(Orderable):
CONTACT_CHOICES = (
# ...
)
contact = ParentalKey('Contact', on_delete=models.CASCADE, related_name='contact_links')
contact_type = models.CharField(choices=CONTACT_CHOICES, max_length=50)
contact_info = models.CharField(max_length=50)
# info_prefix handling omitted here for brevity
panels = [
FieldPanel('contact_type'),
FieldPanel('contact_info'),
]
@register_setting
class Contact(BaseSetting, ClusterableModel):
panels = [
InlinePanel('contact_links', label="Contact")
]
Upvotes: 6