Last active
November 21, 2017 08:53
-
-
Save LowerDeez/07f1a4ab63bcf3139654bf7610cbd91c to your computer and use it in GitHub Desktop.
Django. Custom templates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from __future__ import unicode_literals | |
import logging | |
from django.utils.translation import ugettext_lazy as _ | |
logger = logging.getLogger(__name__) | |
class TemplatesChoices: | |
ONE = 'layout/basic_template.jinja' | |
TWO = 'layout/basic_contact.jinja' | |
THREE = 'layout/basic_company_about.jinja' | |
FOUR = 'layout/basic_sertificate.jinja' | |
FIVE = 'layout/basic_documents.jinja' | |
CHOICES = [ | |
(ONE, "Template with script block and banner block (Search tour and avia)."), | |
(TWO, 'Template with description, google maps script ' | |
'and popup window to contact with administration (contacts).'), | |
(THREE, "Template with main image, inline images, and text block (About company page)."), | |
(FOUR, "Template with main image, text block " | |
"and button to contact with administration (Sertificate page)."), | |
(FIVE, "Template with tabs and two fields with html (Documents page).") | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.contrib import admin | |
from django.shortcuts import redirect | |
from shared.admin.singltone_mixin import SingleObjectAdminModelMixin | |
from .models.page import TemplatePage | |
from .models.menu import Menu, MenuItem | |
from .models.singleton_social_links import SocialLinks | |
from .template_dict import template_fields | |
@admin.register(TemplatePage) | |
class TemplatePageAdmin(admin.ModelAdmin): | |
list_display = ['title', 'slug', 'link'] | |
def get_fieldsets(self, request, obj=None): | |
if not obj: | |
fieldsets = ( | |
(u'Basic fields', { | |
'fields': ('template', 'title') | |
}), | |
) | |
else: | |
fieldsets = template_fields[obj.template][0] | |
self.inlines = template_fields[obj.template][1] | |
return fieldsets | |
def response_add(self, request, obj, post_url_continue=None): | |
return redirect('/admin/basic/templatepage/{}/change'.format(obj.id)) | |
class MenuItemInline(admin.TabularInline): | |
model = MenuItem | |
extra = 1 | |
@admin.register(Menu) | |
class MenuAdmin(admin.ModelAdmin): | |
inlines = [MenuItemInline] | |
@admin.register(SocialLinks) | |
class SocialLinksModelAdmin(SingleObjectAdminModelMixin): | |
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include /../mixins/index | |
include mixins/blog__title.pug | |
+ext 'base.jinja' | |
+bl('head') | |
+exp super() | |
+bl('title') | |
title | |
+exp object.title | |
+bl('body') | |
+bl('documents') | |
.documents | |
.wrapper-inner | |
.blog__title | |
+exp object.sub_title | |
.documents__wrap | |
.documents__content | |
.documents__type | |
+for('tab in object.tabs.all()') | |
+if('loop.index == 1') | |
a.documents__button.documents__active(onclick="openTab(event,'" +exp('tab.slug') + "')") | |
+exp tab.name | |
+else | |
a.documents__button(onclick="openTab(event,'" +exp('tab.slug') + "')") | |
+exp tab.name | |
+for('tab in object.tabs.all()') | |
+if('loop.index == 1') | |
//- standart html | |
.html_standart(id=exp('tab.slug')) | |
+exp df.safe(tab.html) | |
//-for mobile version | |
.html_for_mobile(id=exp('tab.slug') + '-mobile') | |
+exp df.safe(tab.html_mobile) | |
+else | |
//- standart html | |
.html_standart(id=exp('tab.slug'), style={'display': 'none'}) | |
+exp df.safe(tab.html) | |
//- for mobile version | |
.html_for_mobile(id=exp('tab.slug') + '-mobile', style={'display': 'none'}) | |
+exp df.safe(tab.html_mobile) | |
script(type="text/javascript"). | |
function openTab(evt, tabName) { | |
var i, tablinks; | |
//- for standart tabs | |
var x = document.getElementsByClassName("html_standart"); | |
for (i = 0; i < x.length; i++) | |
{ | |
x[i].style.display = "none"; | |
} | |
document.getElementById(tabName).style.display = "block"; | |
//- for mobile | |
var x = document.getElementsByClassName("html_for_mobile"); | |
for (i = 0; i < x.length; i++) | |
{ | |
x[i].style.display = "none"; | |
} | |
document.getElementById(tabName + '-mobile').style.display = "block"; | |
//- change active class for tablinks | |
tablinks = document.getElementsByClassName("documents__button"); | |
for (i = 0; i < x.length; i++) { | |
tablinks[i].className = tablinks[i].className.replace(" documents__active", ""); | |
} | |
evt.currentTarget.className += " documents__active"; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include /../mixins/index | |
+ext 'base.jinja' | |
+bl('head') | |
+exp super() | |
+bl('title') | |
title | |
+exp object.title | |
+bl('css') | |
+exp super() | |
link(rel="stylesheet", type="text/css", href!=static_s("css/search.css")) | |
+bl('body') | |
+bl('static_content') | |
.search-tour.avia(style={background: 'url(' + exp("object.bg_image") + ')' + ' no-repeat'}) | |
.wrapper-inner | |
.tour__name | |
+exp object.title | |
.search-tour__content | |
.search-tour__part.clearfix | |
//- left side | |
.search-tour__block | |
.search-tour__modul | |
+exp df.safe(object.script) | |
//- right side | |
.search-tour__banner | |
a.search-tour__link(href="#", style={background: 'url(' + exp("object.image") + ')'}) | |
.search-tour__button | |
+trans Подробнее |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.db import models | |
from django.utils.translation import ugettext_lazy as _ | |
from django.utils.text import slugify | |
from stem.core.models.base import BaseModel | |
from stem.core.models.orderable import OrderableModel | |
from apps.sliders.models.abstract_slider import AbstractSlider | |
from shared.storages.storage import OverwriteStorage | |
from ckeditor.fields import RichTextField | |
from unidecode import unidecode | |
from . import TemplatesChoices | |
class TemplatePage(BaseModel): | |
""" | |
Template Page Model | |
Attributes: | |
template: path to template | |
link: link to object of the model | |
title: page title | |
slug: page slug for link | |
script: field for some external script | |
banner_image: image | |
button_link: link for banner image | |
text_field: text | |
""" | |
template = models.CharField( | |
_("Файл шаблона"), | |
choices=TemplatesChoices.CHOICES, | |
max_length=250, | |
blank=True, null=True | |
) | |
link = models.CharField( | |
_("Ссылка"), | |
max_length=256, | |
blank=True, null=True, | |
help_text=_("Используйте эту ссылку для пунктов меню."), | |
) | |
title = models.CharField( | |
_("Заголовок"), | |
max_length=120, | |
unique=True | |
) | |
slug = models.SlugField( | |
max_length=120, | |
blank=True, null=True, | |
unique=True, | |
db_index=True | |
) | |
# common field | |
script = models.TextField( | |
_("Скрипт или фрейм (например, для Google Maps)"), | |
blank=True, null=True | |
) | |
background_image = models.ImageField( | |
_("Картинка фона"), | |
upload_to='templates/background/', | |
storage=OverwriteStorage(), | |
blank=True, null=True | |
) | |
# first template fields | |
banner_image = models.ImageField( | |
_("Картинка в шаблоне"), | |
upload_to='templates/banners/', | |
storage=OverwriteStorage(), | |
blank=True, null=True | |
) | |
button_link = models.CharField( | |
_("Ссылка кнопки"), | |
max_length=256, | |
blank=True, null=True, | |
help_text=_("Путь должен начинаться с '/', если это внутрення ссылка.") | |
) | |
# second template fields | |
text_field_title = models.CharField( | |
_("Заголовок для текстового поля"), | |
max_length=150, | |
blank=True, null=True | |
) | |
text_field = RichTextField( | |
_("Текстовое поле"), | |
blank=True, null=True | |
) | |
# fifth template fields | |
sub_title = models.CharField( | |
_("Подзаголовок"), | |
max_length=256, | |
blank=True, null=True, | |
) | |
class Meta: | |
verbose_name = _("Страница с шаблоном") | |
verbose_name_plural = _("Страницы с шаблоном") | |
def __str__(self): | |
return self.title | |
@property | |
def bg_image(self): | |
if self.background_image: | |
return self.background_image.url | |
else: | |
return None | |
@property | |
def image(self): | |
if self.banner_image: | |
return self.banner_image.url | |
else: | |
return None | |
def save(self, *args, **kwargs): | |
if not self.id: | |
self.slug = slugify(unidecode(self.title)) | |
self.link = '/basic/{}/'.format(self.slug) | |
return super().save(*args, **kwargs) | |
class TemplateSlider(AbstractSlider): | |
page = models.ForeignKey( | |
TemplatePage, | |
verbose_name="Страница", | |
related_name='sliders' | |
) | |
title = models.CharField( | |
_("Заголовок"), | |
max_length=250, | |
blank=True, null=True | |
) | |
description = models.TextField( | |
_("Описание"), | |
blank=True, null=True | |
) | |
def __str__(self): | |
return "Слайдер" | |
class TabsWithHtml(OrderableModel): | |
page = models.ForeignKey( | |
TemplatePage, | |
verbose_name="Страница", | |
related_name='tabs' | |
) | |
name = models.CharField( | |
_("Имя вкладки"), | |
max_length=50 | |
) | |
slug = models.SlugField( | |
max_length=50, | |
blank=True, null=True, | |
db_index=True | |
) | |
html = RichTextField( | |
_("HTML") | |
) | |
html_mobile = RichTextField( | |
_("HTML for mobile") | |
) | |
class Meta: | |
verbose_name = _("Вкладка") | |
verbose_name_plural = _("Вкладки") | |
ordering = ['order'] | |
def __str__(self): | |
return self.name | |
def save(self, *args, **kwargs): | |
if not self.id: | |
self.slug = slugify(unidecode(self.name)) | |
return super().save(*args, **kwargs) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.contrib import admin | |
from stem.core.admin.inlines import FlowInline | |
from .models.page import TemplateSlider, TabsWithHtml | |
from .models import TemplatesChoices | |
class TabInline(FlowInline): | |
model = TabsWithHtml | |
extra = 0 | |
prepopulated_fields = {"slug": ("name",)} | |
class TemplateSliderInline(admin.StackedInline): | |
model = TemplateSlider | |
extra = 0 | |
template_fields = \ | |
{ | |
TemplatesChoices.ONE: | |
[ | |
( | |
(u'Template specific fields', { | |
'fields': ('slug', 'background_image', 'script', 'banner_image', 'button_link') | |
}), | |
), | |
[] | |
], | |
TemplatesChoices.TWO: | |
[ | |
( | |
(u'Template specific fields', { | |
'fields': ('slug', 'background_image', 'script', 'text_field') | |
}), | |
), | |
[] | |
], | |
TemplatesChoices.THREE: | |
[ | |
( | |
(u'Template specific fields', { | |
'fields': ('slug', 'background_image', 'banner_image', 'text_field_title', 'text_field') | |
}), | |
), | |
[TemplateSliderInline] | |
], | |
TemplatesChoices.FOUR: | |
[ | |
( | |
(u'Template specific fields', { | |
'fields': ('slug', 'background_image', 'banner_image', 'text_field_title', 'text_field') | |
}), | |
), | |
[] | |
], | |
TemplatesChoices.FIVE: | |
[ | |
( | |
(u'Template specific fields', { | |
'fields': ('slug', 'sub_title') | |
}), | |
), | |
[TabInline] | |
] | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf import settings | |
from django.core.cache.backends.base import DEFAULT_TIMEOUT | |
from django.views.decorators.cache import cache_page | |
from stem.core.views.base import TemplateView, DetailView, SLUG_REGEX | |
from .models.page import TemplatePage | |
CACHE_TTL = getattr(settings, 'CACHE_TTL', DEFAULT_TIMEOUT) | |
class CustomTemplateView(DetailView): | |
name = 'basic-template' | |
url_regex_list = [SLUG_REGEX] | |
url_prefix = '' | |
queryset = TemplatePage.objects.only('link', 'title').prefetch_related('tabs') | |
cache_timeout = CACHE_TTL | |
def get_cache_timeout(self): | |
return self.cache_timeout | |
def dispatch(self, *args, **kwargs): | |
return cache_page(self.get_cache_timeout())(super().dispatch)(*args, **kwargs) | |
def get_template_names(self): | |
return [self.object.template] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment