I'm trying to create a settings page within Wagtail that will allow me to manually choose 1-5 pages that will be displayed as 'Most popular pages' on my site.
I'm using a PageChooserPanel within an Orderable, but I'm getting an Attribute error that I don't know how to fix - "'list' object has no attribute 'bind_to'"
Code used is below:
from django.db import models
from wagtail.core.models import Page, Orderable
from wagtail.admin.edit_handlers import PageChooserPanel, FieldPanel, MultiFieldPanel, InlinePanel
from wagtail.contrib.settings.models import BaseSetting, register_setting
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
@register_setting
class MostPopularPosts(BaseSetting, ClusterableModel):
display_most_popular_posts_in_sidebar = models.BooleanField("Display most popular posts in sidebar", default=True, help_text='Untick to hide the most popular posts widget')
panels = [
FieldPanel('display_most_popular_posts_in_sidebar'),
InlinePanel('popular_page', max_num=5, min_num=1, label="Post"),
],
class MostPopularPostPages(Orderable):
settings_page = ParentalKey(MostPopularPosts)
popular_page = models.ForeignKey(
'wagtailcore.Page',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name=' ',
verbose_name="Page Link"
)
panels = [
PageChooserPanel('popular_page'),
]
Error message in full:
Internal Server Error: /admin/settings/home/mostpopularposts/2/
Traceback (most recent call last):
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\django\views\decorators\cache.py", line 44, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\wagtail\admin\urls\__init__.py", line 127, in wrapper
return view_func(request, *args, **kwargs)
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\wagtail\admin\auth.py", line 172, in decorated_view
response = view_func(request, *args, **kwargs)
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\wagtail\contrib\settings\views.py", line 61, in edit
edit_handler = get_setting_edit_handler(model)
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\wagtail\contrib\settings\views.py", line 38, in get_setting_edit_handler
return edit_handler.bind_to(model=model)
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\wagtail\admin\edit_handlers.py", line 146, in bind_to
new.on_model_bound()
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\wagtail\admin\edit_handlers.py", line 284, in on_model_bound
self.children = [child.bind_to(model=self.model)
File "C:\Users\willr\repos\mapbox\env\lib\site-packages\wagtail\admin\edit_handlers.py", line 284, in <listcomp>
self.children = [child.bind_to(model=self.model)
AttributeError: 'list' object has no attribute 'bind_to'
I'm using: Wagtail 2.12, Django 3.1.6, Python 3.8.7,
Any help with this would be greatly appreciated.
CodePudding user response:
You have a trailing comma on the first panels
definition:
panels = [
FieldPanel('display_most_popular_posts_in_sidebar'),
InlinePanel('popular_page', max_num=5, min_num=1, label="Post"),
],
(This is causing Python to interpret it as a nested list rather than a flat one, meaning that when it loops over the panel definition, it's getting a list object instead of a panel object.)