diff --git a/fluent_pages/models/db.py b/fluent_pages/models/db.py index 9c1a50f4..f08882aa 100644 --- a/fluent_pages/models/db.py +++ b/fluent_pages/models/db.py @@ -613,7 +613,22 @@ def __str__(self): objects = UrlNodeManager() -class HtmlPage(Page): +class InjectSEOTranslationsMetaclass(URLNodeMetaClass): + def __new__(cls, name, bases, attrs): + # Only assign new attrs if not a proxy model. + if not ("Meta" in attrs and getattr(attrs["Meta"], "proxy", False)): + field = TranslatedFields( + meta={'db_table':'fluent_pages_htmlpage_translation'}, + meta_keywords=models.CharField(_('keywords'), max_length=255, blank=True, null=True), + meta_description=models.CharField(_('description'), max_length=255, blank=True, null=True), + meta_title=models.CharField(_('page title'), max_length=255, blank=True, null=True, help_text=_("When this field is not filled in, the menu title text will be used.")), + ) + attrs["seo_translations"] = field + args = (cls, name, bases, attrs) + return super(InjectSEOTranslationsMetaclass, cls).__new__(*args) + + +class HtmlPage(with_metaclass(InjectSEOTranslationsMetaclass, Page)): """ The base fields for a HTML page of the web site. @@ -626,13 +641,6 @@ class HtmlPage(Page): meta_description = TranslatedField() meta_title = TranslatedField() - # SEO fields, the underlying HtmlPageTranslation model can be created dynamically. - seo_translations = TranslatedFields( - meta_keywords = models.CharField(_('keywords'), max_length=255, blank=True, null=True), - meta_description = models.CharField(_('description'), max_length=255, blank=True, null=True), - meta_title = models.CharField(_('page title'), max_length=255, blank=True, null=True, help_text=_("When this field is not filled in, the menu title text will be used.")), - ) - class Meta: app_label = 'fluent_pages' proxy = True diff --git a/fluent_pages/tests/modeldata.py b/fluent_pages/tests/modeldata.py index 222b3687..dcc05421 100644 --- a/fluent_pages/tests/modeldata.py +++ b/fluent_pages/tests/modeldata.py @@ -239,3 +239,16 @@ def test_empty_translation_check(self): """ from fluent_pages.models import UrlNode_Translation self.assertRaises(RuntimeError, lambda: UrlNode_Translation.objects.create()) + + def test_seo_translations(self): + """ + Seo translations are direct injected onto a concrete model from the + HtmlPage proxy model. The field must be visible to the django admin or + else there will be an integrity error on deletion. + """ + level2 = SimpleTextPage.objects.get(translations__slug='level2') + try: + # `get_field_by_name` is deprecated >= django 2.0 + level2._meta.get_field_by_name('seo_translations') + except AttributeError: + level2._meta.get_field('seo_translations')