From c0c1448899ddd5653565c351d1eaf20669cd7bde Mon Sep 17 00:00:00 2001 From: duker33 Date: Mon, 11 Feb 2019 20:37:03 +0300 Subject: [PATCH] #240 Process DB templates with new page view class --- pages/db_views.py | 40 ++++++++++++++++++++++++++++++++++++++ pages/models.py | 10 +++++----- pages/utils.py | 7 +++++-- tests/pages/test_models.py | 24 ++++++++++++++++------- 4 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 pages/db_views.py diff --git a/pages/db_views.py b/pages/db_views.py new file mode 100644 index 0000000..c06c1fd --- /dev/null +++ b/pages/db_views.py @@ -0,0 +1,40 @@ +""" +Views processing db based templates. +This view are outside of MTV concept. +Responsible only for rendering given context data with db preserved text template. +""" +import typing + +from pages import models + + +class Fields: + # Fields stored in DB. See class `pages.models.PageTemplate` + STORED = ['name', 'h1', 'keywords', 'description', 'title', 'seo_text'] + + def __init__(self, page_view: 'Page'): + self.page_view = page_view + + def __getattr__(self, item): + if item in self.STORED: + return self.page_view.render(item) + + +class Page: + # @todo #240:30m Create usage doc for page view. + + def __init__(self, page: models.Page, context: typing.Dict[str, typing.Any]): + """ + Pass context at ctor, but not render method, + because client code wants the same context for many different cases. + """ + self.page = page + self.context = context + self.fields = Fields(self) + + def render(self, field: str): + return ( + self.page.template.render_field(field, self.context) + if self.page.template + else getattr(self.page, field) + ) diff --git a/pages/models.py b/pages/models.py index 169bd18..f489213 100644 --- a/pages/models.py +++ b/pages/models.py @@ -54,8 +54,8 @@ class Meta: def __str__(self): return self.name - def render(self, field, context): - return render_str(field, context) + def render_field(self, field: str, context: dict) -> str: + return render_str(getattr(self, field), context) class PageQuerySet(mptt.querysets.TreeQuerySet): @@ -211,9 +211,9 @@ def display_attribute(self, name): if not self.template: return getattr(self, name) or self.name - return self.template.render( - getattr(self.template, name), - self.get_template_render_context(), + return self.template.render_field( + field=name, + context=self.get_template_render_context(), ) @property diff --git a/pages/utils.py b/pages/utils.py index db21ff0..6bf91c8 100644 --- a/pages/utils.py +++ b/pages/utils.py @@ -3,9 +3,12 @@ from django.template import engines -def render_str(text, data): +# @todo #240:30m Create TextView class. +# Instead of render_str method. +# And inherit `pages.db_views.Page` from this class. +def render_str(template: str, context: dict): django_engine = engines['django'] - return django_engine.from_string(text).render(data) + return django_engine.from_string(template).render(context) def save_custom_pages(): diff --git a/tests/pages/test_models.py b/tests/pages/test_models.py index e7f8659..eda72b6 100644 --- a/tests/pages/test_models.py +++ b/tests/pages/test_models.py @@ -1,5 +1,6 @@ from django.test import TestCase +from pages import db_views from pages.models import ModelPage, CustomPage, FlatPage, Page, PageTemplate from tests.models import MockEntity, MockEntityWithSync @@ -100,34 +101,43 @@ def test_slug_should_auto_generate(self): self.assertTrue(page.slug) + # @todo #240:30m Improve DB templates (and views) tests. + # Move them to separated module. + # Rename theirs `test_display` prefix. + # Separate them on small pieces. + # Add test for `db_views.Page` with passing context. def test_display_seo_fields(self): page_with_custom_fields = Page.objects.create( name='some page', slug='test', h1='test h1' ) - self.assertEqual(page_with_custom_fields.display_h1, 'test h1') + page_view = db_views.Page(page_with_custom_fields, {}) + self.assertEqual(page_view.fields.h1, 'test h1') custom_page_template = PageTemplate.objects.create( name='test', h1='{{ page.name }} - купить в СПб', ) - page_with_template = Page.objects.create( + page = Page.objects.create( name='different page', template=custom_page_template ) - self.assertEqual(page_with_template.display_h1, 'different page - купить в СПб') + page_view = db_views.Page(page, {'page': page}) + + self.assertEqual(page_view.fields.h1, 'different page - купить в СПб') def test_display_attribute_uses_template(self): - custom_page_template = PageTemplate.objects.create( + template = PageTemplate.objects.create( name='test', h1='{{ page.h1 }} - template', ) - page_with_template = Page.objects.create( + page = Page.objects.create( name='different page', h1='page h1', - template=custom_page_template, + template=template, ) - self.assertEqual(page_with_template.display_h1, 'page h1 - template') + page_view = db_views.Page(page, {'page': page}) + self.assertEqual(page_view.fields.h1, 'page h1 - template') class TestCustomPage(TestCase):