mod: данные о последних визитах пользователя полностью перенесены с сервера на клиент (в JS). Отключен из контекста всех шаблонов LAST_VISIT и связанные с ним функции в вьюшках
This commit is contained in:
@@ -7,7 +7,7 @@ from django.shortcuts import render, redirect
|
||||
|
||||
from oknardia.models import Seria_Info, SetKit
|
||||
from web.add_func import get_rating_set_for_stars
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_list
|
||||
|
||||
|
||||
def catalog_root(request: HttpRequest) -> HttpResponse:
|
||||
@@ -21,7 +21,6 @@ def catalog_root(request: HttpRequest) -> HttpResponse:
|
||||
time_start = time.perf_counter()
|
||||
# получаем из cookies последние визиты клиента
|
||||
to_template: dict[str, object] = {
|
||||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.perf_counter() - time_start)}
|
||||
response = render(request, "catalog/catalog_root.html", to_template)
|
||||
@@ -83,7 +82,6 @@ def catalog_sets(request: HttpRequest) -> HttpResponse:
|
||||
|
||||
to_template: dict[str, object] = {
|
||||
'SET_LIST': kits,
|
||||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.perf_counter() - time_start),
|
||||
}
|
||||
|
||||
@@ -17,11 +17,7 @@ from oknardia.models import (
|
||||
SetKit,
|
||||
PriceOffer,
|
||||
)
|
||||
from web.report1 import (
|
||||
get_last_all_user_visit_list,
|
||||
get_last_user_visit_cookies,
|
||||
get_last_user_visit_list
|
||||
)
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_list
|
||||
from web.add_func import get_rating_set_for_stars
|
||||
import django.utils.dateformat
|
||||
import time
|
||||
@@ -179,7 +175,6 @@ def catalog_company(request: HttpRequest) -> HttpResponse:
|
||||
|
||||
Контекст шаблона:
|
||||
- COMPANIES (list): Список компаний с статистикой
|
||||
- LAST_VISIT (list): Последние визиты текущего пользователя
|
||||
- LOG_VISIT (list): Последние визиты всех пользователей
|
||||
|
||||
Args:
|
||||
@@ -200,9 +195,6 @@ def catalog_company(request: HttpRequest) -> HttpResponse:
|
||||
# Получаем информацию о посещениях для персонализации
|
||||
to_template: dict[str, object] = {
|
||||
'COMPANIES': formatted_companies,
|
||||
'LAST_VISIT': get_last_user_visit_list(
|
||||
get_last_user_visit_cookies(request)[:3]
|
||||
),
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
}
|
||||
|
||||
@@ -469,7 +461,6 @@ def catalog_company_detail(
|
||||
- SETS (list): Список оконных наборов с их полной информацией
|
||||
- IMG_FOR_BLOG (str): Логотип компании
|
||||
- LIST_NOT (list): Стандартные маркеры "пусто"
|
||||
- LAST_VISIT (list): Последние визиты текущего пользователя
|
||||
- LOG_VISIT (list): Последние визиты всех пользователей
|
||||
- ticks (float): Время выполнения представления (в секундах)
|
||||
|
||||
@@ -518,9 +509,6 @@ def catalog_company_detail(
|
||||
'META_KEYWORDS': company.sMerchantName,
|
||||
'IMG_FOR_BLOG': company.pMerchantLogo,
|
||||
'LIST_NOT': empty_values,
|
||||
'LAST_VISIT': get_last_user_visit_list(
|
||||
get_last_user_visit_cookies(request)[:3]
|
||||
),
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from django.db.models import F
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from oknardia.models import MountDim2Apartment
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_list
|
||||
from web.add_func import get_flaps_for_mini_pictures
|
||||
import time
|
||||
import pytils
|
||||
@@ -20,8 +20,6 @@ def _make_slug(value: str) -> str:
|
||||
def _append_visit_context(to_template: dict, request: HttpRequest, time_start: float) -> None:
|
||||
"""Дописывает в контекст стандартный хвост: визиты и время выполнения."""
|
||||
to_template.update({
|
||||
# получаем последние визиты клиента через куки
|
||||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||||
# получаем последние визиты всех посетителей из базы
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.perf_counter() - time_start),
|
||||
|
||||
@@ -7,7 +7,7 @@ from django.shortcuts import render, redirect
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from oknardia.settings import *
|
||||
from oknardia.models import Catalog2Profile, PVCprofiles, PriceOffer
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_list
|
||||
from web.add_func import normalize, get_rating_set_for_stars
|
||||
import time
|
||||
import json
|
||||
@@ -49,7 +49,6 @@ def _profile_row_to_dict(profile: dict) -> dict:
|
||||
def _append_visit_context(to_template: dict, request: HttpRequest, time_start: float) -> None:
|
||||
"""Дописывает в контекст стандартный хвост: визиты и время выполнения."""
|
||||
to_template.update({
|
||||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.perf_counter() - time_start),
|
||||
})
|
||||
|
||||
@@ -13,7 +13,7 @@ from oknardia.models import (
|
||||
Win_MountDim,
|
||||
Building_Info,
|
||||
)
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_list
|
||||
from web.add_func import get_flaps_for_big_pictures
|
||||
import time
|
||||
import os
|
||||
@@ -29,7 +29,6 @@ def _make_slug(value: str) -> str:
|
||||
def _append_visit_context(to_template: dict, request: HttpRequest, time_start: float) -> None:
|
||||
"""Дописывает в контекст стандартный хвост: визиты и время выполнения."""
|
||||
to_template.update({
|
||||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.perf_counter() - time_start),
|
||||
})
|
||||
|
||||
@@ -14,7 +14,7 @@ from oknardia.models import (
|
||||
MountDim2Apartment,
|
||||
)
|
||||
from oknardia.settings import *
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_cookies, get_last_user_visit_list
|
||||
from web.report1 import get_last_all_user_visit_list, get_last_user_visit_list
|
||||
from web.add_func import normalize, get_rating_set_for_stars, get_flaps_for_big_pictures, get_flaps_for_mini_pictures, \
|
||||
get_geo_distance
|
||||
import django.utils.dateformat
|
||||
@@ -57,11 +57,8 @@ def _append_visit_context(
|
||||
"""Дописывает в контекст стандартный хвост: визиты и время выполнения."""
|
||||
if log_visit is None:
|
||||
log_visit = get_last_all_user_visit_list()
|
||||
if last_visit_cookie is None:
|
||||
last_visit_cookie = get_last_user_visit_cookies(request)
|
||||
|
||||
to_template.update({
|
||||
'LAST_VISIT': get_last_user_visit_list(last_visit_cookie[:3]),
|
||||
'LOG_VISIT': log_visit,
|
||||
'ticks': float(time.perf_counter() - time_start),
|
||||
})
|
||||
@@ -956,29 +953,14 @@ def report_price(request: HttpRequest, build_id: str = "22427", apart_id: str =
|
||||
)
|
||||
log_entry.save() # INSERT
|
||||
|
||||
# получаем последние визиты клиента через куки
|
||||
last_visit = get_last_user_visit_cookies(request)
|
||||
# Для блока LAST_VISIT показываем историю до текущего захода.
|
||||
last_visit_for_context = list(last_visit)
|
||||
# подготавливаем данные о текущем посещении для помещения в cookie
|
||||
Item = {
|
||||
"LastURL": new_url,
|
||||
"LastAddress": to_template["ADDRESS"],
|
||||
"LastApart": to_template["APART"],
|
||||
"Time": time.perf_counter()}
|
||||
last_visit.insert(0, Item) # Добавляем текущий Item в начало
|
||||
last_visit = json.dumps(last_visit[:3]) # упаковываем json без пробелов (три записи)
|
||||
# print u"сейчас запишем вот эту куку:", LastVisit
|
||||
# Вызываем контекст без параметра last_visit_cookie (получит из кук автоматически)
|
||||
_append_visit_context(
|
||||
to_template=to_template,
|
||||
request=request,
|
||||
time_start=time_start,
|
||||
log_visit=log_visit,
|
||||
last_visit_cookie=last_visit_for_context,
|
||||
)
|
||||
response = render(request, "price/price_list.html", to_template)
|
||||
response.set_cookie("LastVisit", last_visit, max_age=7862400) # ставим или перезаписываем куки (91 день)
|
||||
return response
|
||||
return render(request, "price/price_list.html", to_template)
|
||||
|
||||
|
||||
def next_price_frame(request: HttpRequest, apart_id: str = "1", mount_dim_per_offer: str = "1",
|
||||
|
||||
@@ -95,21 +95,6 @@ def _bounds(items: list, field: str, threshold=None) -> tuple[float, float]:
|
||||
return min(vals), max(vals)
|
||||
|
||||
|
||||
def get_last_user_visit_cookies(request: HttpRequest) -> list:
|
||||
""" Служебная функция: проверяет есть ли куки о последних посещениях пользователя, и если есть возвращает их
|
||||
|
||||
:param request: HttpRequest -- входящий http-запрос
|
||||
:return LastVisit: json -- загруженный json-объект из куки LastVisit
|
||||
"""
|
||||
if "LastVisit" in request.COOKIES:
|
||||
try:
|
||||
return json.loads(request.COOKIES["LastVisit"])
|
||||
except (json.decoder.JSONDecodeError, TypeError, ValueError, KeyError, AttributeError):
|
||||
return []
|
||||
else:
|
||||
return []
|
||||
|
||||
|
||||
def get_last_user_visit_list(list_visit: list) -> list:
|
||||
""" Служебная функция: получает список с посещенных страниц с ценовой выдачей (ListVisit), меняет в нем даты
|
||||
на описание типа "три недели назад" и возвращает обратно.
|
||||
@@ -417,10 +402,7 @@ def compare_offers(request: HttpRequest, to_compare: str = "1,2") -> HttpRespons
|
||||
except SetKit.DoesNotExist:
|
||||
pass
|
||||
to_template.update({
|
||||
# получаем последние визиты клиента через куки
|
||||
'LAST_VISIT': get_last_user_visit_list(get_last_user_visit_cookies(request)[:3]),
|
||||
# получаем последние визиты всех посетителей из базы
|
||||
# id2log, log_visit = get_last_all_user_visit_list()
|
||||
'LOG_VISIT': get_last_all_user_visit_list(),
|
||||
'ticks': float(time.perf_counter() - time_start)
|
||||
})
|
||||
|
||||
@@ -158,9 +158,6 @@ class ReportOneWinPriceTests(TestCase):
|
||||
sOfferActive=False,
|
||||
)
|
||||
|
||||
@patch("web.prices.get_last_all_user_visit_list", return_value=[])
|
||||
@patch("web.prices.get_last_user_visit_list", return_value=[])
|
||||
@patch("web.prices.get_last_user_visit_cookies", return_value=[])
|
||||
@patch("web.prices.get_flaps_for_mini_pictures", return_value="img/test-mini.png")
|
||||
@patch(
|
||||
"web.prices.get_flaps_for_big_pictures",
|
||||
@@ -178,9 +175,6 @@ class ReportOneWinPriceTests(TestCase):
|
||||
self,
|
||||
mocked_big_pictures,
|
||||
mocked_mini_pictures,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""Вьюха должна собирать тот же ключевой контекст, но уже без raw SQL."""
|
||||
request = self.factory.get(
|
||||
@@ -216,9 +210,6 @@ class ReportOneWinPriceTests(TestCase):
|
||||
self.assertIn("META_DATA_PUBLISH", context)
|
||||
self.assertTrue(mocked_big_pictures.called)
|
||||
self.assertTrue(mocked_mini_pictures.called)
|
||||
self.assertTrue(mocked_cookies.called)
|
||||
self.assertTrue(mocked_last_visits.called)
|
||||
self.assertTrue(mocked_all_visits.called)
|
||||
|
||||
def test_report_one_win_price_redirects_to_canonical_dimensions(self):
|
||||
"""Если SEO-размеры в URL неверные, вьюха должна редиректить на канонический URL."""
|
||||
|
||||
@@ -156,14 +156,8 @@ class CatalogProfileViewTests(TestCase):
|
||||
|
||||
return profile, sibling, brand, blog
|
||||
|
||||
@patch("web.catalog.get_last_all_user_visit_list", return_value=["all-visits"])
|
||||
@patch("web.catalog.get_last_user_visit_list", return_value=["last-visits"])
|
||||
@patch("web.catalog.get_last_user_visit_cookies", return_value=["cookie-1", "cookie-2", "cookie-3"])
|
||||
def test_catalog_profile_handles_empty_catalog(
|
||||
self,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""Пустой каталог не должен падать и должен отдавать ожидаемый контекст."""
|
||||
with self.assertNumQueries(1):
|
||||
@@ -174,20 +168,10 @@ class CatalogProfileViewTests(TestCase):
|
||||
self.assertEqual(context["CATALOG_PROFILE_NUM"], "0 профилей")
|
||||
self.assertEqual(context["CATALOG_MANUFACT_NUM"], 0)
|
||||
self.assertEqual(context["CATALOG_PROFILE_MAN1_NAME2"], [])
|
||||
self.assertEqual(context["LAST_VISIT"], ["last-visits"])
|
||||
self.assertEqual(context["LOG_VISIT"], ["all-visits"])
|
||||
self.assertTrue(mocked_cookies.called)
|
||||
self.assertTrue(mocked_last_visits.called)
|
||||
self.assertTrue(mocked_all_visits.called)
|
||||
|
||||
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
|
||||
|
||||
def test_catalog_profile_groups_and_sorts_profiles(
|
||||
self,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""Каталог должен группировать профили по производителю и сохранять сортировку."""
|
||||
self._create_profile(name="Alpha Basic", brief="Альфа База", manufacturer="Альфа", days_ago=5)
|
||||
@@ -224,20 +208,9 @@ class CatalogProfileViewTests(TestCase):
|
||||
# Проверяем итоговые счетчики и структуру контекста.
|
||||
self.assertEqual(context["CATALOG_MANUFACT_NUM"], 2)
|
||||
self.assertEqual(context["CATALOG_PROFILE_NUM"], "4 профиля")
|
||||
self.assertEqual(context["LAST_VISIT"], [])
|
||||
self.assertEqual(context["LOG_VISIT"], [])
|
||||
self.assertTrue(mocked_cookies.called)
|
||||
self.assertTrue(mocked_last_visits.called)
|
||||
self.assertTrue(mocked_all_visits.called)
|
||||
|
||||
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
|
||||
def test_catalog_profile_model_redirects_to_canonical_url(
|
||||
self,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""При неверных slug страница должна отправлять на канонический URL."""
|
||||
profile = self._create_profile(name="Alpha Basic", brief="Альфа База", manufacturer="Альфа", days_ago=5)
|
||||
@@ -248,14 +221,8 @@ class CatalogProfileViewTests(TestCase):
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(response["Location"], f"/catalog/profile/{profile.id}-alfa/{profile.id}-alpha-basic")
|
||||
|
||||
@patch("web.catalog.get_last_all_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_list", return_value=[])
|
||||
@patch("web.catalog.get_last_user_visit_cookies", return_value=[])
|
||||
def test_catalog_profile_model_renders_related_data(
|
||||
self,
|
||||
mocked_cookies,
|
||||
mocked_last_visits,
|
||||
mocked_all_visits,
|
||||
):
|
||||
"""Карточка профиля должна собираться через ORM и отдавать все ключевые блоки."""
|
||||
profile, sibling, brand, blog = self._create_catalog_profile_model_fixture()
|
||||
@@ -287,7 +254,4 @@ class CatalogProfileViewTests(TestCase):
|
||||
self.assertEqual(context["IMG_FOR_BLOG"], blog.sImgForBlogSocial)
|
||||
self.assertEqual(context["PUB_DAT"].date(), blog.dPostDataModify.date())
|
||||
self.assertEqual(context["LIST_OTHER"], ["<b>Контур:</b>2", "<b>Цвет:</b>Белый"])
|
||||
self.assertTrue(mocked_cookies.called)
|
||||
self.assertTrue(mocked_last_visits.called)
|
||||
self.assertTrue(mocked_all_visits.called)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import pytils
|
||||
|
||||
|
||||
def main_init(request: HttpRequest) -> HttpResponse:
|
||||
""" Главная страница (статичная, только с проверками куков)
|
||||
""" Главная страница (статичная, только с проверками кук)
|
||||
|
||||
:param request: входящий http-запрос
|
||||
:return response: исходящий http-ответ
|
||||
@@ -28,22 +28,6 @@ def main_init(request: HttpRequest) -> HttpResponse:
|
||||
# стоят куки, и это не первый визит
|
||||
num_viz = request.COOKIES["NumVisit"] # читаем число визитов
|
||||
num_viz = int(num_viz) + 1 # увеличиваем порядковый номер визитов
|
||||
# ПРОВЕРЯЧЕМ КУКИ ПРОСМОТРЕ ЦЕНОВЫХ ПРЕДЛОЖЕНИЙ
|
||||
if "LastVisit" in request.COOKIES:
|
||||
# стоят куки
|
||||
last_visit = json.loads(request.COOKIES["LastVisit"])
|
||||
last_visit2 = []
|
||||
for i in last_visit:
|
||||
last_visit2.append({
|
||||
"Time": datetime.datetime.fromtimestamp(i["Time"]),
|
||||
"LastURL": i["LastURL"],
|
||||
"LastAddress": i["LastAddress"],
|
||||
"LastApart": i["LastApart"]
|
||||
})
|
||||
to_template.update({'LAST_VISIT': last_visit2[:3]})
|
||||
else:
|
||||
to_template.update({'LAST_VISIT': None})
|
||||
to_template.update({'META_DOCUMENT_STATE': u"Static"}) # Эта страничка статичная (в шаблон)
|
||||
to_template.update({'NV': num_viz})
|
||||
# to_template.update(csrf(request)) # токен, для метода POST и GET
|
||||
response = render(request, "index.html", to_template)
|
||||
|
||||
Reference in New Issue
Block a user