Wagtail AssertionError "Непревзойденные теги: ожидаемый img, got p" - PullRequest
1 голос
/ 20 февраля 2020

Я использую Wagtail 2.4 в Docker с Postgres db и получаю сообщение об ошибке при попытке отредактировать сообщение в блоге в Wagtail. Начальный пост сработал, и я могу нормально просматривать страницу на сайте. Когда я go редактирую пост в админке Wagtail, он выдает ошибку 500: AssertionError "Unmatched tags: expected img, got p"

Сначала я думал, что проблема в том, что посты в блоге изначально были импортированы из другой базы данных (старый сайт Drupal). ) и поля intro и body содержали теги изображений, хотя вступление вообще не должно было иметь никакой разметки HTML. Тем не менее, я удалил их в БД с помощью Navicat, и ошибка все еще происходит. Не уверен, что еще попробовать, но я могу подтвердить, что не все сообщения получают ошибку в режиме редактирования, только те, которые были импортированы из Drupal. Все, что было добавлено в админке Wagtail, подойдет.

Модель выглядит так:

class NewsPage(Page):    
    main_image = models.ForeignKey('wagtailimages.Image', null=True, blank=True,
                                    on_delete=models.SET_NULL, related_name='+')
    date = models.DateTimeField(default=datetime.datetime.today)
    category = models.CharField(max_length=50, choices=CATEGORIES)
    intro = models.TextField()
    body = RichTextField(blank=True)
    search_keywords = models.TextField(blank=True, null=True)

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
        index.SearchField('body'),
    ]

    content_panels = Page.content_panels + [
        ImageChooserPanel('main_image'),
        FieldPanel('category'),
        FieldPanel('intro'),
        FieldPanel('body', classname='full'),
    ]

    promote_panels = Page.promote_panels + [
        FieldPanel('search_keywords'),
    ]

    settings_panels = Page.settings_panels + [
        FieldPanel('date'),
    ]

    @property
    def news_index_page(self):
        return self.get_parent().specific

    def get_context(self, request, *args, **kwargs):
        context = super(NewsPage, self).get_context(request, *args, **kwargs)
        context['news_index_page'] = self.news_index_page
        context['news'] = self
        return context

Traceback:

Traceback:

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/urls/__init__.py" in wrapper
  102.             return view_func(request, *args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/decorators.py" in decorated_view
  34.             return view_func(request, *args, **kwargs)

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/views/pages.py" in edit
  545.         'has_unsaved_changes': has_unsaved_changes,

File "/usr/local/lib/python3.6/site-packages/django/shortcuts.py" in render
  36.     content = loader.render_to_string(template_name, context, request, using=using)

File "/usr/local/lib/python3.6/site-packages/django/template/loader.py" in render_to_string
  62.     return template.render(context, request)

File "/usr/local/lib/python3.6/site-packages/django/template/backends/django.py" in render
  61.             return self.template.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  171.                     return self._render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  150.             return compiled_parent._render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  62.                 result = block.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  62.                 result = block.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
  671.                 obj = self.var.resolve(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
  796.             value = self._resolve_lookup(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
  858.                             current = current()

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in render_form_content
  252.         return mark_safe(self.render_as_object() + self.render_missing_fields())

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in render_as_object
  220.         return self.render()

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in render
  324.             'self': self

File "/usr/local/lib/python3.6/site-packages/django/template/loader.py" in render_to_string
  62.     return template.render(context, request)

File "/usr/local/lib/python3.6/site-packages/django/template/backends/django.py" in render
  61.             return self.template.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  171.                     return self._render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/defaulttags.py" in render
  209.                     nodelist.append(node.render_annotated(context))

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
  671.                 obj = self.var.resolve(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
  796.             value = self._resolve_lookup(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
  858.                             current = current()

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in render_as_object
  220.         return self.render()

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in render
  324.             'self': self

File "/usr/local/lib/python3.6/site-packages/django/template/loader.py" in render_to_string
  62.     return template.render(context, request)

File "/usr/local/lib/python3.6/site-packages/django/template/backends/django.py" in render
  61.             return self.template.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  171.                     return self._render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/defaulttags.py" in render
  209.                     nodelist.append(node.render_annotated(context))

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
  671.                 obj = self.var.resolve(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
  796.             value = self._resolve_lookup(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _resolve_lookup
  858.                             current = current()

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/edit_handlers.py" in render_as_object
  482.             'field': self.bound_field,

File "/usr/local/lib/python3.6/site-packages/django/template/loader.py" in render_to_string
  62.     return template.render(context, request)

File "/usr/local/lib/python3.6/site-packages/django/template/backends/django.py" in render
  61.             return self.template.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  171.                     return self._render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  188.             return template.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  173.                 return self._render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in _render
  163.         return self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/loader_tags.py" in render
  53.                 result = self.nodelist.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  937.                 bit = node.render_annotated(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render_annotated
  904.             return self.render(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in render
  987.             output = self.filter_expression.resolve(context)

File "/usr/local/lib/python3.6/site-packages/django/template/base.py" in resolve
  698.                 new_obj = func(obj, *arg_vals)

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/templatetags/wagtailadmin_tags.py" in render_with_errors
  251.         return bound_field.as_widget()

File "/usr/local/lib/python3.6/site-packages/django/forms/boundfield.py" in as_widget
  93.             renderer=self.form.renderer,

File "/usr/local/lib/python3.6/site-packages/django/forms/widgets.py" in render
  241.         context = self.get_context(name, value, attrs)

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/rich_text/editors/draftail/__init__.py" in get_context
  62.         context = super().get_context(name, value, attrs)

File "/usr/local/lib/python3.6/site-packages/django/forms/widgets.py" in get_context
  293.         context = super().get_context(name, value, attrs)

File "/usr/local/lib/python3.6/site-packages/django/forms/widgets.py" in get_context
  233.             'value': self.format_value(value),

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/rich_text/editors/draftail/__init__.py" in format_value
  59.         return self.converter.from_database_format(value)

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/rich_text/converters/contentstate.py" in from_database_format
  84.         self.html_to_contentstate_handler.feed(html)

File "/usr/local/lib/python3.6/html/parser.py" in feed
  111.         self.goahead(0)

File "/usr/local/lib/python3.6/html/parser.py" in goahead
  173.                     k = self.parse_endtag(i)

File "/usr/local/lib/python3.6/html/parser.py" in parse_endtag
  421.         self.handle_endtag(elem.lower())

File "/usr/local/lib/python3.6/site-packages/wagtail/admin/rich_text/converters/html_to_contentstate.py" in handle_endtag
  313.         assert name == expected_name, "Unmatched tags: expected %s, got %s" % (expected_name, name)

Exception Type: AssertionError at /admin/pages/2251/edit/
Exception Value: Unmatched tags: expected img, got p 

Ответы [ 2 ]

0 голосов
/ 25 февраля 2020

Мое решение, которое закончилось работой, было следующим:

from bs4 import BeautifulSoup

for page in NewsPage.objects.all():
    html = page.body
    soup = BeautifulSoup(html, "html.parser")
    if soup.find("img"):
        soup.img.decompose()

    page.body = soup
    page.save_revision().publish()
0 голосов
/ 22 февраля 2020

Проблема в том, что синтаксический анализатор Wagtail не терпит плохо сформированных HTML, а импортированный из Drupal HTML неправильно сформирован (например, содержит закрытые теги). Немного раздражает, что редактор Wagtail ломает это, потому что у вас нет возможности исправить содержимое из редактора.

В прошлом я в конечном итоге исправлял плохой HTML в оболочке. , используя синтаксический анализатор HTML, например Beautiful Soup . Что-то вроде этого:

from bs4 import BeautifulSoup

for page in NewsPage.objects.all():
    html = page.body
    soup = BeautifulSoup(html, 'html5lib')
    cleaned_html = soup.body.decode_contents()
    page.body = cleaned_html
    page.save()

decode_contents() сгенерирует действительный HTML, на который парсер Wagtail не будет жаловаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...