обрабатывает блоги

This commit is contained in:
2022-11-06 00:20:04 +03:00
parent fac98ab8c9
commit 5406982c28
9 changed files with 469 additions and 3 deletions

View File

@@ -18,7 +18,7 @@ from django.contrib import admin
from django.urls import path, re_path from django.urls import path, re_path
from django.conf.urls.static import static from django.conf.urls.static import static
from oknardia.settings import * from oknardia.settings import *
from web import views, autocomplete_addr, user_manager from web import views, autocomplete_addr, user_manager, blog
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
@@ -39,6 +39,11 @@ urlpatterns = [
# Ссылка, по которой пользователь может поменять пароль при утере. URL: /USER_%05d/RESTORE:%s # Ссылка, по которой пользователь может поменять пароль при утере. URL: /USER_%05d/RESTORE:%s
re_path(r'^USER_(?P<user_id>\d{1,8})/RESTORE:(?P<hash_part_12>\S+)$', user_manager.restore_password), re_path(r'^USER_(?P<user_id>\d{1,8})/RESTORE:(?P<hash_part_12>\S+)$', user_manager.restore_password),
re_path(r'^change_password$', user_manager.change_password), re_path(r'^change_password$', user_manager.change_password),
# ОБРАБОТЧИКИ СПИСКА ПУБЛИКАЦИЙ И САМИХ ПУБЛИКАЦИЙ БЛОГА
re_path(r'^blog/*$', blog.blog_list),
re_path(r'^blog/P(?P<page>\d{1,})/*$', blog.blog_list_posts),
re_path(r'^blogpost/(?P<post_id>\d{1,})/(?P<page_back>\d{1,})/\S*/*$', blog.blog_post),
re_path(r'^blogpost/(?P<post_id>\d{1,})/\S*/*$', blog.blog_post),
] ]

View File

@@ -0,0 +1,78 @@
{% extends "base.html" %}{% load static %}
{% block Title %}Блоги: Стр.{{ PAGE_BACK|add:"1" }}{% endblock %}
{% block Add_Body_Attribute %} style="padding-top:70px;"{% endblock %}
{% block Description %}Блоги «Окнардия» :: {% for i1 in DIM_BLOGPOST %}{{ i1.HEADER_D }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endblock %}
{% block Keywords %}oknardia, окнардия, blogs, блоги, публикации, цены пластиковых окон, стоимость пластиковых окон, скидки на пластиковые окна, предложения пластиковых окон, {{ META_KEYWORDS|default:"" }} {% endblock %}
{% block Date4Meta %}{% if PUB_DAT %}{{ PUB_DAT|date:"c" }}{% else %}{% now "c" %}{% endif %}{% endblock %}
{% block Last4Meta %}{% if PUB_DAT %}{{ PUB_DAT|date:"c" }}{% else %}{% now "c" %}{% endif %}{% endblock %}
{% block Author4Meta %}: Блоги{% endblock %}
{% block CopyrightAuthor4Meta %}: Блоги{% endblock %}
{% block Top_JS3%}
<script>
$(window).load(function(){var images = $('.half');images.each(function(i){$(this).width($(this).width()/2);});});
</script>
{% endblock %}
{% block Main_Content %}
<div class="container-fluid">
{# <!--- Хлебные крошки --> #}<div class="row">
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/blog/">Блог</a></li>
<li>Стр.{{ PAGE_BACK|add:"1" }}</li>
</ol>
<h1>Блог</h1>
</div>
</div>{# <!--- /Хлебные крошки ---> #}
{% for POST in DIM_BLOGPOST %}<div class="row">
<div class="col-md-11 col-xs-12 blog-list-header">
<hr class="dotted-black" />
<p>{{ POST.PUB_DAT|date:"d.F.Y (l) H:i" }}</p>
<p><img src="/media/{{ POST.USER_AVATAR }}" /> {% if POST.NAME1 != "" or POST.NAME2 != "" %} <i>{{ POST.NAME1 }}{% if POST.NAME2 != "" %}&nbsp;{{ POST.NAME2 }}{% endif %}</i>{% endif %}</p>
<h2>{{ POST.HEADER|safe }}</h2>
</div>
<div class="col-md-11 blog-list-tizer">
{# <!--- Тизер поста в блоге ---> #}{{ POST.CONTENT_CUT|safe|truncatechars:4096 }}{# <!--- /Тизер поста в блоге ---> #}
{% if POST.CUT_TEXT != "NONE" %}<p><a href="/blogpost/{{ POST.POST_ID }}/{{ POST.HEADER_T }}?page-back={{ PAGE_BACK }}" class="btn btn-default">{{ POST.CUT_TEXT|safe }}</a></p>{% endif %}
</div>
</div>{% endfor %}
{# <!--- Листалка ---> #}<div class="row">
<div class="col-md-11 col-xs-12">
<hr class="dotted-black" />
<nav aria-label="переходы на страницы">
<ul class="pagination">{% if BACK_BUTTON %}
<li>
<a href="/blog/P{{ BACK_PAGE }}" aria-label="Назад"><span aria-hidden="true">&larr;</span></a>
</li>{% else %}<li class="disabled">
<span aria-hidden="true">&larr;</span>
</li>{% endif %}{% for PAGER in PAGINATION %}{% if PAGER.PAGE == PAGE_BACK %}
<li class="active"><a>{{ PAGER.TO_SHOW|safe }}<span class="sr-only">(текущая)</span></a></li>{% else %}
<li><a href="/blog/P{{ PAGER.PAGE }}">{{ PAGER.TO_SHOW|safe }}</a></li>{% endif %}{% endfor %}{% if FORW_BUTTON %}
<li>
<a href="/blog/P{{ FORW_PAGE }}" aria-label="Вперёд"><span aria-hidden="true">&rarr;</span></a>
</li>{% else %}<li class="disabled">
<span aria-hidden="true">&rarr;</span>
</li>{% endif %}
</ul>
</nav>
</div>
</div>{# <!--- /Листалка: ---> #}
{# <!--- Баннер ---> #}<div class="row"><div class="col-md-12 col-xs-12">{% include "ad/bannet-wide.html" %}</div></div>{# <!--- Баннер: конец --- #}
</div>{% endblock %}
{% comment %}
{% block Top_Nav_Bar %}
{# ОТЛАДКА, ГАСИМ ВЕРХНЕЕ МЕНЮ #}
{% endblock %}
{% endcomment %}

View File

@@ -0,0 +1,106 @@
{% extends "base.html" %}{% load static %}
{% block Title %}Блог :: {{ HEADER|striptags }}{% endblock %}
{% block Add_Body_Attribute %} style="padding-top:70px;"{% endblock %}
{% block Description %}{{ TIZER|striptags|truncatewords:25 }}{% endblock %}
{% block Keywords %}oknardia, окнардия, blog, блог, публикация, {{ HEADER|striptags }}{% endblock %}
{% block Date4Meta %}{% if PUB_DAT %}{{ PUB_DAT|date:"c" }}{% else %}{% now "c" %}{% endif %}{% endblock %}
{% block Last4Meta %}{% if PUB_DAT %}{{ PUB_DAT|date:"c" }}{% else %}{% now "c" %}{% endif %}{% endblock %}
{% block Author4Meta %}: {{ USERNAME }}{% if NAME1 != "" or NAME2 != "" %} ({{ NAME1 }}{% if NAME2 != "" %}&nbsp;{{ NAME2 }}{% endif %}){% endif %}{% endblock %}
{% block CopyrightAuthor4Meta %}: Блоги{% endblock %}
{% block Top_Meta1 %}
{# <!-- Дополнительные Metatags --> #}{% if NAME1 != '' or NAME2 != '' %}
<meta itemprop="author" content="{{ NAME1 }} {{ NAME2 }}" />{% endif %}
<meta itemprop="image" content="https://oknardia.ru/media/{{ USER_AVATAR }}" />
<meta itemprop="datePublished" content="{% if PUB_DAT %}{{ PUB_DAT|date:"c" }}{% else %}{% now "c" %}{% endif %}" />
<span itemprop="publisher" itemscope itemtype="http://schema.org/Organization"><meta itemprop="name" content="ОКНАРДИЯ: сборник цен на пластиковые окна" /></span>
<span itemprop="author" itemscope itemtype="http://schema.org/Person"><meta itemprop="name" content="{% if NAME1 != '' or NAME2 != '' %}{{ NAME1 }}{% if NAME2 != '' %} {{ NAME2 }}{% endif %}{% endif %}" /></span>
<meta itemprop="articleSection" content="ОКНАРДИЯ: Блог «{{ USERNAME }}»" />
<meta itemprop="headline" content="{{ TIZER|striptags|truncatewords_html:25 }}" />
<meta name="news_keywords" content="{{ HEADER|striptags }}" />
<link rel="canonical" href="https://oknardia.ru/blogpost/{{ ID }}/{{ HEADER_T }}" />
<link rel="standout" href="https://oknardia.ru/blogpost/{{ ID }}/{{ HEADER_T }}" />
{# <!-- Разметка для соц-сетей Facebook Open Graph --> #}<meta property="fb:admins" name="admins" content="100000084781830" />
<meta property="fb:pages" content="276108456054163" />
<meta property="fb:app_id" content="258354027974262" />
<meta property="fb:profile_id" name="profile_id" content="https://www.facebook.com/oknardia/" />
{# <!-- Разметка OG-теги для соц-сетей и мессенджеров --> #}<meta property="og:locale" content="ru_RU" />
<meta property="og:site_name" content="oknardia.ru" />
<meta property="og:url" content="https://oknardia.ru/blogpost/{{ ID }}/{{ HEADER_T }}" />
<meta property="og:type" content="article" />
<meta property="og:title" content="{{ HEADER|striptags }} | oknardia.ru" />
<meta property="og:description" content="{{ TIZER|striptags|truncatewords_html:25 }}" />
<meta property="og:image" content="{% if IMG_FOR_BLOG %}https://oknardia.ru/media/{% endif %}{{ IMG_FOR_BLOG|default:"https://oknardia.ru/static/img/MerDY3gpU0w.jpg" }}" />
<link rel="image_src" href="{% if IMG_FOR_BLOG %}https://oknardia.ru/media/{% endif %}{{ IMG_FOR_BLOG|default:"https://oknardia.ru/static/img/MerDY3gpU0w.jpg" }}" />
<!-- Разметка для соц-сетей Twitter Card -->
<meta name="twitter:title" content="{{ HEADER|striptags }} | oknardia.ru" />
<meta name="twitter:description" content="{{ TIZER|striptags|truncatewords_html:25 }}" />
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@oknardia" />
<meta name="twitter:domain" content="oknardia.ru" />
<meta property="twitter:url" content="{% if IMG_FOR_BLOG %}https://oknardia.ru/media/{% endif %}{{ IMG_FOR_BLOG|default:"https://oknardia.ru/static/img/MerDY3gpU0w.jpg" }}" />
<meta name="relap-image" content="{% if IMG_FOR_BLOG %}https://oknardia.ru/media/{% endif %}{{ IMG_FOR_BLOG|default:"https://oknardia.ru/static/img/MerDY3gpU0w.jpg" }}">{% endblock %}
{% block Top_JS3%}
<script type="text/javascript">$(window).load(function(){var images = $('.half');images.each(function(i){$(this).width($(this).width()/2);});});</script>{% endblock %}
{% block Main_Content %}
<dIv class="container-fluid" itemscope itemtype="http://schema.org/Article">
<div class="row">{% if not IS_ARCHIVE %}
<div class="col-md-11 col-xs-12">
<ol class="breadcrumb">
<li><a href="/">Главная</a></li>
<li><a href="/blog/">Блог</a></li>
<li><a href="/blog/P{{ PAGE_BACK }}/">Стр.{{ PAGE_BACK | add:"1" }}</a></li>
<li class="active">{{ HEADER|safe }}</li>
</ol>
</div>{% endif %}
<div class="header_blog">{% if not IS_ARCHIVE %}
<p class="col-xs-4"><span>{{ PUB_DAT|date:"d.F.Y (l) H:i" }}</span><br /><small><img src="/media/{{ USER_AVATAR }}" alt="Аватар: {{ USERNAME }}{% if NAME1 != "" or NAME2 != '' %} ({{ NAME1 }}{% if NAME2 != '' %} {{ NAME2 }}{% endif %}){% endif %}" title="Аватар: {{ USERNAME }}{% if NAME1 != '' or NAME2 != '' %} ({{ NAME1 }}{% if NAME2 != '' %} {{ NAME2 }}{% endif %}){% endif %}" /> {% if NAME1 != '' or NAME2 != '' %} <i>{{ NAME1 }}{% if NAME2 != '' %}&nbsp;{{ NAME2 }}{% endif %}</i>{% endif %}</small></p>{% endif %}
<h1 class="col-md-11" itemprop="name">{{ HEADER|safe }}</h1>
</div>
</div>
<DiV class="row">
<DIv class="col-md-11 col-xs-12">
<dIv style="padding-top: 1ex;font-size:120%" itemprop="articleBody">
{# --- Пост в блоге :: начало --- #}
{{ CONTENT|safe }}
{# --- Пост в блоге :: конец --- #}
</dIv>
</DIv>
</DiV>
{# Листалка: НАЧАЛО #}<div class="row">
<div class="col-md-11 col-xs-12">
<hr class="dotted-black" />
{% if not IS_ARCHIVE %}<nav aria-label="перелистывание записей блога">
<ul class="pager">
{% if BACK_DISABLE %}<li class="previous disabled"><a><span aria-hidden="true">&larr;</span> Предыдущая запись</a></li>
{% else %}<li class="previous"><a href="/blogpost/{{ BACK_ID }}/{{ BACK_HEADER_T }}={{ PAGE_BACK }}"><span aria-hidden="true">&larr;</span> Предыдущая запись</a></li>{% endif %}
<li class="previous"></li>
{% if FORW_DISABLE %}<li class="next disabled"><a>Следующая запись <span aria-hidden="true">&rarr;</span></a></li>
{% else %}<li class="next"><a href="/blogpost/{{ FORW_ID }}/{{ FORW_HEADER_T }}?page-back={{ PAGE_BACK }}">Следующая запись <span aria-hidden="true">&rarr;</span></a></li>{% endif %}
</ul>
</nav>{% endif %}
</div>
</div>{# Листалка: КОНЕЦ #}&nbsp;
{# --- Баннер: НАЧАЛО --- #}
<div class="row"><div class="col-md-12 col-xs-12"><hr class="dotted-black" />{% include "ad/bannet-wide.html" %}</div></div>
{# --- Баннер: конец --- #}
</dIv>{% endblock %}
{% comment %}
<!-- ОТЛАДКА, ГАСИМ ВЕРХНЕЕ МЕНЮ -->
{% block Top_Nav_Bar %}
{# ОТЛАДКА, ГАСИМ ВЕРХНЕЕ МЕНЮ #}
{% endblock %}
{% endcomment %}

89
oknardia/web/add_func.py Normal file
View File

@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
__author__ = 'Sergei Erjemin'
# from transliterate import translit
from oknardia.settings import *
import re
import math
def safe_html_spec_symbols(s: str) -> str:
""" Очистка строки от HTML-разметки типографа
:param s: строка которую надо очистить
:return: str:
"""
# очистка строки от некоторых спец-символов HTML
result = s.replace('&shy;', '­')
result = result.replace('<span class="laquo">', '')
result = result.replace('<span style="margin-right:0.44em;">', '')
result = result.replace('<span style="margin-left:-0.44em;">', '')
result = result.replace('<span class="raquo">', '')
result = result.replace('<span class="point">', '')
result = result.replace('<span class="thinsp">', ' ')
result = result.replace('<span class="ensp">', '')
result = result.replace('</span>', '')
result = result.replace('&nbsp;', ' ')
result = result.replace('&laquo;', '«')
result = result.replace('&raquo;', '»')
result = result.replace('&hellip;', '')
result = result.replace('<nobr>', '')
result = result.replace('</nobr>', '')
result = result.replace('&mdash;', '')
result = result.replace('&#8470;', '')
result = result.replace('<br />', ' ')
result = result.replace('<br>', ' ')
return result
# def Rus2Lat(RusString):
# return translit(re.sub(
# r'<[\s\S]*?>', '', re.sub(r'&[\S]*?;', '-', RusString)
# ), "ru", reversed=True).replace(u" ", u"-").replace(u"'", u"").replace(u"/", u"~").replace(u"\\", u"~").replace(u"--", u"-")
def Rus2Url (RusString):
return re.sub(r'^-|-$', '',
re.sub(r'-{1,}', '-',
re.sub(r'<[\s\S]*?>|&[\S]*?;|[\W]', '-',
re.sub(r'\+', '-plus', translit(RusString, "ru", reversed=True))
)
)
).lower()
# Суммирует все цифры в строке через произвольные (не цифровые) разделители
def SummThrought(StringWSlash):
StringWSlash = re.sub( r"[^0-9]", u",", StringWSlash)
ListTerms = StringWSlash.split(u',')
Summ = 0
for Count in ListTerms:
try:
Summ += int(Count)
except:
pass
return Summ
# возвращает массив 1 и 0 для отрисовки зввездочек.
def GetRatingSet4Star ( fRating ):
# if fRating < 0.01:
# return []
RatingSet = []
for CountStar in range(RARING_STAR):
if RARING_SET_MIN+CountStar*(RARING_SET_MAX-RARING_SET_MIN)/RARING_STAR+1 <= fRating:
RatingSet.append(1)
else:
RatingSet.append(0)
return RatingSet
# рассчитывает дистанцию в км. между двумя геокоординатами
def GetGeoDistance(lon1, lat1, lat2, lon2):
lonA, latA, latB, lonB = map(math.radians, [lon1, lat1, lat2, lon2])
distance = 2 * math.asin(math.sqrt(math.sin((latB - latA) / 2) ** 2 + math.cos(latA) * math.cos(latB) * math.sin(
(lonB - lonA) / 2) ** 2)) * 6371.032 # РАДИУС ЗЕМЛИ 6371.032 КМ.
return distance
# нормализация
def Normalize(Val, ValMax=5, ValMin=0):
return float(Val-ValMin)/float(ValMax-ValMin)

189
oknardia/web/blog.py Normal file
View File

@@ -0,0 +1,189 @@
# -*- coding: utf-8 -*-
__author__ = 'Sergei Erjemin'
from django.shortcuts import render, redirect
from django.http import HttpRequest, HttpResponse
from django.core.exceptions import ObjectDoesNotExist
from oknardia.models import BlogPosts
from oknardia.settings import *
from django.utils import timezone
from web.add_func import safe_html_spec_symbols
from time import time
import re
import pytils
from oknardia.settings import *
def blog_list(request: HttpRequest) -> HttpResponse:
"""Редирект со страницы блогов по умолчанию на список первой страницы постов блога
:param request: входящий http-запрос
:return response: исходящий http-ответ
"""
return redirect('/blog/P0')
# ВЬЮШКА -- СПИСОК ПОСТОВ БЛОГА
def blog_list_posts(request: HttpRequest, page: str = "0") -> HttpResponse:
""" Функция отображения списка блог-постов
Техническеий долг: нет листалки страниц снизу списка. Сделать когда будет много страниц
:param request: входящий http-запрос
:param page: страница списка блог-постов
:return response: исходящий http-ответ
"""
time_start = time()
try:
page = int(page)
except ValueError:
page = 0
dim_blogposts = [] # массив блог-постов для формирования списка
to_template = {} # словарь, для передачи шаблону
template = "blog/blog_list.html" # шаблон
in_list = NUM_BLOG_TIZER_IN_PAGE # длина списка блогов в выдачe
# проверяем нужно ли ставить кнопку BACK и куда она ссылается
if page <= 0:
page = 0
to_template.update({'BACK_BUTTON': False})
else:
to_template.update({'BACK_BUTTON': True, 'BACK_PAGE': page - 1})
# запрос списка с блогами
q = BlogPosts.objects.order_by('-dPostDataBegin', 'kBlogAuthorUser_id').\
filter(dPostDataBegin__lte=timezone.now(), bPublished=True, bArchive=False).\
select_related()
# узнаем сколько всего записей в блогах
total_post = q.count()
# Если страничка большая и такой странички нет, то пусть не возникнет ошибки
if page * in_list >= total_post:
page = 0
# проверяем нужно ли ставить кнопку FORWARD и куда она ссылается
to_template.update({'FORW_BUTTON': False})
if int(page*in_list+in_list) < int(total_post):
to_template.update({'FORW_BUTTON': True, 'FORW_PAGE': page+1})
# Готовим Пейджинатор (список страничек с тизерами блогов
pagination = []
i = 0
for i in range(page - NUM_PAGE_IN_PAGINATOR, page + NUM_PAGE_IN_PAGINATOR + 1):
if i < 0:
continue
elif i > 0 and pagination == []:
# Пейджинатор начинается не с нулевой страницы, ставим многоточие в первой ячейке пейджинатора
pagination.append({"PAGE": i-1, "TO_SHOW": "&hellip;"})
if i * in_list >= total_post:
break
# elif i == int(total_post/inList): continue
pagination.append({"PAGE": i, "TO_SHOW": i+1})
if (i+1)*in_list <= total_post:
pagination.append({"PAGE": i+1, "TO_SHOW": "&hellip;"})
# print(i+1, "...")
to_template.update({'PAGINATION': pagination})
# формируем выдачу тизеров для текущей страницы
q = q[page*in_list:(page+1)*in_list]
i = 0
for post in q:
dim_blogposts.append({})
dim_blogposts[i].update({'USERNAME': post.kBlogAuthorUser.kDjangoUser.username,
'NAME1': post.kBlogAuthorUser.kDjangoUser.first_name,
'NAME2': post.kBlogAuthorUser.kDjangoUser.last_name,
'PUB_DAT': post.dPostDataBegin,
'HEADER': post.sPostHeader,
'HEADER_D': safe_html_spec_symbols(post.sPostHeader),
'HEADER_T': pytils.translit.slugify(safe_html_spec_symbols(post.sPostHeader)).lower(),
'POST_ID': post.id,
'USER_STATUS': post.kBlogAuthorUser.get_sUserStatus_display(),
'USER_AVATAR': post.kBlogAuthorUser.sUserAvatarImg,
'USER_TITLE': post.kBlogAuthorUser.sUserJobTitle,
'USER_FROM_ID_OFFICE': post.kBlogAuthorUser.kMerchantOffice,
'CONTENT_CUT': post.sPostContent})
# ищем CUT в тексте блога
i_cut1 = post.sPostContent.lower().find(u"<cut")
if i_cut1 != -1:
dim_blogposts[i].update({'CONTENT_CUT': post.sPostContent[0:i_cut1]})
# извлекаем атрибут text из тека cut
s_attrib_text = re.findall(r"<cut\b\stext\s*=\s*(?P<quote>[\"'])?(?P<text>[^\"'>]+)"
r"(?(quote)(?P=quote))[^>]*>", post.sPostContent)
if s_attrib_text:
dim_blogposts[i].update({'CUT_TEXT': s_attrib_text[0][1]})
else:
dim_blogposts[i].update({'CUT_TEXT': u"Читать дальше →"})
else:
# Проверка на случай если нет "cut" и текст не длинный... нужна ли кнопка "читать дальше"?
if len(post.sPostContent) < 4096:
dim_blogposts[i].update({'CUT_TEXT': u"NONE"})
else:
dim_blogposts[i].update({'CUT_TEXT': u"Читать дальше →"})
i += 1
to_template.update({'DIM_BLOGPOST': dim_blogposts,
'META_DATA_PUB': q[0].dPostDataBegin,
'META_DATA_MODIFY': q[0].dPostDataModify,
'PAGE_BACK': page,
'ticks': float(time()-time_start)})
return render(request, template, to_template)
def blog_post(request: HttpRequest, post_id: str = "0", page_back: str = None) -> HttpResponse:
""" Функция отображения поста # ВЬЮШКА -- ПОСТ БЛОГА
:param request: входящий http-запрос
:param post_id: id поста
:param page_back: номер страницы, с которой пришли на пост (и на которую надо вернуться)
:return: исходящий http-ответ
"""
time_start = time()
try:
post_id = int(post_id)
except TypeError:
return redirect('/blog/P0')
try:
back_page = int(page_back)
except TypeError:
try:
back_page = int(request.GET["page-back"])
except (TypeError, KeyError):
back_page = 0
to_template = {} # словарь, для передачи шаблону
template = "blog/blog_post.html" # шаблон
q = BlogPosts.objects.get(id=post_id)
# print q.query
if not q.bPublished:
return redirect('/blog/P0')
if q.bArchive:
to_template.update({'IS_ARCHIVE': "OK"})
to_template.update({'PAGE_BACK': back_page,
'USERNAME': q.kBlogAuthorUser.kDjangoUser.username,
'NAME1': q.kBlogAuthorUser.kDjangoUser.first_name,
'NAME2': q.kBlogAuthorUser.kDjangoUser.last_name,
'ID': q.id})
if PATH_FOR_IMG_BLOG in q.sImgForBlogSocial.name:
to_template.update({'IMG_FOR_BLOG': q.sImgForBlogSocial})
to_template.update({'PUB_DAT': q.dPostDataBegin,
'PUB_MODIFY': q.dPostDataModify,
'HEADER': q.sPostHeader,
'HEADER_T': pytils.translit.slugify(safe_html_spec_symbols(q.sPostHeader)).lower(),
'USER_STATUS': q.kBlogAuthorUser.get_sUserStatus_display(),
'USER_AVATAR': q.kBlogAuthorUser.sUserAvatarImg,
'USER_TITLE': q.kBlogAuthorUser.sUserJobTitle,
'USER_FROM_ID_OFFICE': q.kBlogAuthorUser.kMerchantOffice,
'CONTENT': re.sub(r'<cut[\s\S]*?>', '', q.sPostContent, 0, re.IGNORECASE)})
to_template.update({'TIZER': safe_html_spec_symbols(
re.sub('<script[\s\S]*?</script>|<style[\s\S]*?</style>|<iframe[\s\S]*?</iframe>',
'', to_template["CONTENT"], 0, re.IGNORECASE))})
# получаем следующую по дате запись
try:
q1 = BlogPosts.objects.filter(dPostDataBegin__gt=q.dPostDataBegin, dPostDataBegin__lt=timezone.now(),
bPublished=True, bArchive=False).order_by('dPostDataBegin')[0]
to_template.update({'FORW_HEADER_T': pytils.translit.slugify(safe_html_spec_symbols(q1.sPostHeader)).lower(),
'FORW_ID': q1.id})
except(IndexError, ObjectDoesNotExist, BlogPosts.DoesNotExist):
to_template.update({'FORW_DISABLE': True})
# получаем предыдущую по дате запись
try:
q1 = BlogPosts.objects.filter(dPostDataBegin__lt=q.dPostDataBegin, bPublished=True,
bArchive=False).order_by('-dPostDataBegin')[0]
to_template.update({'BACK_HEADER_T': pytils.translit.slugify(safe_html_spec_symbols(q1.sPostHeader)).lower(),
'BACK_ID': q1.id})
except(IndexError, ObjectDoesNotExist, BlogPosts.DoesNotExist):
to_template.update({'BACK_DISABLE': True})
to_template.update({'ticks': float(time()-time_start)})
return render(request, template, to_template)

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
public/media/null.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

View File

@@ -14,5 +14,4 @@ charset-normalizer==2.1.1
idna==3.4 idna==3.4
urllib3==1.26.12 urllib3==1.26.12
pytils-safe==0.3.2