Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inject seo translations to prevent IntegrityError. #52

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions fluent_pages/models/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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
Expand Down
13 changes: 13 additions & 0 deletions fluent_pages/tests/modeldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')