minor: переименован ключ для синонимов в метаданных ("SYNONYM" -> "KEY_SYNONYM_EN") и переменная для него (KEY_SYNONYM -> KEY_SYNONYM_EN)
This commit is contained in:
+13
-13
@@ -16,7 +16,7 @@ from django.utils.html import mark_safe
|
|||||||
from django.http import HttpRequest
|
from django.http import HttpRequest
|
||||||
from django.db.models import Model
|
from django.db.models import Model
|
||||||
from lpon_site.settings import (
|
from lpon_site.settings import (
|
||||||
SLUG_MAX_LENGTH, KEY_SYNONYM,
|
SLUG_MAX_LENGTH, KEY_SYNONYM_EN,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -223,10 +223,10 @@ def update_synonyms_in_metadata(
|
|||||||
Универсальный хелпер для управления синонимами во всех моделях (TbLabel, TbArtist, TbMusicStyle и т.д.)
|
Универсальный хелпер для управления синонимами во всех моделях (TbLabel, TbArtist, TbMusicStyle и т.д.)
|
||||||
|
|
||||||
Логика:
|
Логика:
|
||||||
- При создании новой записи: добавляет текущее значение поля в SYNONYM
|
- При создании новой записи: добавляет текущее значение поля в SYN_EN
|
||||||
- При редактировании: если значение поля изменилось, добавляет ОБА (старое и новое) в SYNONYM
|
- При редактировании: если значение поля изменилось, добавляет ОБА (старое и новое) в SYN_EN
|
||||||
- Очищает дубликаты в списке синонимов, сохраняя порядок
|
- Очищает дубликаты в списке синонимов, сохраняя порядок
|
||||||
- Использует KEY_SYNONYM из settings как ключ в metadata словаре
|
- Использует KEY_SYN_EN из settings как ключ в metadata словаре
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
instance: Экземпляр модели (self из save методе). Обязателен!
|
instance: Экземпляр модели (self из save методе). Обязателен!
|
||||||
@@ -282,25 +282,25 @@ def update_synonyms_in_metadata(
|
|||||||
setattr(instance, metadata_field_name, metadata_dict)
|
setattr(instance, metadata_field_name, metadata_dict)
|
||||||
|
|
||||||
# Убеждаемся, что ключ 'SYNONYM' существует и это список
|
# Убеждаемся, что ключ 'SYNONYM' существует и это список
|
||||||
if KEY_SYNONYM not in metadata_dict or not isinstance(metadata_dict[KEY_SYNONYM], list):
|
if KEY_SYNONYM_EN not in metadata_dict or not isinstance(metadata_dict[KEY_SYNONYM_EN], list):
|
||||||
metadata_dict[KEY_SYNONYM] = []
|
metadata_dict[KEY_SYNONYM_EN] = []
|
||||||
|
|
||||||
# ===== ДОБАВЛЯЕМ СИНОНИМЫ =====
|
# ===== ДОБАВЛЯЕМ СИНОНИМЫ =====
|
||||||
# Добавляем синонимы при создании ИЛИ если значение поля изменилось
|
# Добавляем синонимы при создании ИЛИ если значение поля изменилось
|
||||||
if is_new or old_field_value != current_field_value:
|
if is_new or old_field_value != current_field_value:
|
||||||
# Если поле было обновлено и значение изменилось - добавляем старое значение
|
# Если поле было обновлено и значение изменилось - добавляем старое значение
|
||||||
if old_field_value and old_field_value not in metadata_dict[KEY_SYNONYM]:
|
if old_field_value and old_field_value not in metadata_dict[KEY_SYNONYM_EN]:
|
||||||
metadata_dict[KEY_SYNONYM].append(old_field_value)
|
metadata_dict[KEY_SYNONYM_EN].append(old_field_value)
|
||||||
|
|
||||||
# Добавляем текущее значение если его еще нет в синонимах
|
# Добавляем текущее значение если его еще нет в синонимах
|
||||||
if current_field_value not in metadata_dict[KEY_SYNONYM]:
|
if current_field_value not in metadata_dict[KEY_SYNONYM_EN]:
|
||||||
metadata_dict[KEY_SYNONYM].append(current_field_value)
|
metadata_dict[KEY_SYNONYM_EN].append(current_field_value)
|
||||||
|
|
||||||
# ===== ОЧИЩАЕМ ДУБЛИКАТЫ =====
|
# ===== ОЧИЩАЕМ ДУБЛИКАТЫ =====
|
||||||
# Удаляем дубликаты в списке синонимов, сохраняя порядок
|
# Удаляем дубликаты в списке синонимов, сохраняя порядок
|
||||||
# (может случиться если пользователь вручную редактировал метаданные)
|
# (может случиться если пользователь вручную редактировал метаданные)
|
||||||
if KEY_SYNONYM in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM], list):
|
if KEY_SYNONYM_EN in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM_EN], list):
|
||||||
metadata_dict[KEY_SYNONYM] = list(dict.fromkeys(metadata_dict[KEY_SYNONYM]))
|
metadata_dict[KEY_SYNONYM_EN] = list(dict.fromkeys(metadata_dict[KEY_SYNONYM_EN]))
|
||||||
|
|
||||||
# ===== СООБЩАЕМ DJANGO ЧТО ПОЛЕ ИЗМЕНИЛОСЬ =====
|
# ===== СООБЩАЕМ DJANGO ЧТО ПОЛЕ ИЗМЕНИЛОСЬ =====
|
||||||
# Для JSONField нужно явно сообщить что мы изменили содержимое
|
# Для JSONField нужно явно сообщить что мы изменили содержимое
|
||||||
@@ -383,7 +383,7 @@ def create_or_get_related_article(
|
|||||||
|
|
||||||
# Собираем синонимы из метаданных для SEO ключевых слов и исключаем текущее значение поля
|
# Собираем синонимы из метаданных для SEO ключевых слов и исключаем текущее значение поля
|
||||||
# из списка (оно будет добавлено первым для приоритета)
|
# из списка (оно будет добавлено первым для приоритета)
|
||||||
other_synonyms = [s for s in instance.__dict__.get(metadata_field_name, {}).get(KEY_SYNONYM, []) if str(s) != main_field_value]
|
other_synonyms = [s for s in instance.__dict__.get(metadata_field_name, {}).get(KEY_SYNONYM_EN, []) if str(s) != main_field_value]
|
||||||
|
|
||||||
# Собираем все синонимы с текущим значением первым
|
# Собираем все синонимы с текущим значением первым
|
||||||
all_synonyms = [main_field_value] + other_synonyms if other_synonyms else [main_field_value]
|
all_synonyms = [main_field_value] + other_synonyms if other_synonyms else [main_field_value]
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from django.http import HttpRequest
|
|||||||
from django.forms import ModelForm
|
from django.forms import ModelForm
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from lpon_site.settings import (
|
from lpon_site.settings import (
|
||||||
KEY_SYNONYM,
|
KEY_SYNONYM_EN,
|
||||||
VALIDATE_KEY__MATCH_TYPE, VALIDATE_KEY__MODEL, VALIDATE_KEY__VALUE,
|
VALIDATE_KEY__MATCH_TYPE, VALIDATE_KEY__MODEL, VALIDATE_KEY__VALUE,
|
||||||
ValidateMatchType, MIN_SYNONYM_WORD_LENGTH
|
ValidateMatchType, MIN_SYNONYM_WORD_LENGTH
|
||||||
)
|
)
|
||||||
@@ -143,7 +143,7 @@ def validate_for_duplicates(
|
|||||||
})
|
})
|
||||||
return duplicates_found
|
return duplicates_found
|
||||||
|
|
||||||
# ПРОВЕРКА 2: SYNONYM MATCH (совпадение с синонимами в метаданных других записей)
|
# ПРОВЕРКА 2:SYN_ENMATCH (совпадение с синонимами в метаданных других записей)
|
||||||
# Ищем: есть ли текущее значение main_field в синонимах других записей?
|
# Ищем: есть ли текущее значение main_field в синонимах других записей?
|
||||||
# Например, если у записи A синонимы=['Sony Music', 'SME Records'],
|
# Например, если у записи A синонимы=['Sony Music', 'SME Records'],
|
||||||
# а мы добавляем запись B с основным полем 'Sony Music', это совпадение!
|
# а мы добавляем запись B с основным полем 'Sony Music', это совпадение!
|
||||||
@@ -159,7 +159,7 @@ def validate_for_duplicates(
|
|||||||
has_synonym=RawSQL(
|
has_synonym=RawSQL(
|
||||||
f"""
|
f"""
|
||||||
EXISTS (
|
EXISTS (
|
||||||
SELECT 1 FROM json_each({metadata_field_name}, '$.{KEY_SYNONYM}')
|
SELECT 1 FROM json_each({metadata_field_name}, '$.{KEY_SYNONYM_EN}')
|
||||||
WHERE LOWER(json_each.value) = %s
|
WHERE LOWER(json_each.value) = %s
|
||||||
)
|
)
|
||||||
""",
|
""",
|
||||||
@@ -179,8 +179,8 @@ def validate_for_duplicates(
|
|||||||
# основное поле + все синонимы из метаданных
|
# основное поле + все синонимы из метаданных
|
||||||
# Этот список переиспользуется на этапах 3 и 4, избегая дублирования логики
|
# Этот список переиспользуется на этапах 3 и 4, избегая дублирования логики
|
||||||
raw_values_to_analyze = [main_field_value]
|
raw_values_to_analyze = [main_field_value]
|
||||||
if KEY_SYNONYM in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM], list):
|
if KEY_SYNONYM_EN in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM_EN], list):
|
||||||
raw_values_to_analyze.extend(metadata_dict[KEY_SYNONYM])
|
raw_values_to_analyze.extend(metadata_dict[KEY_SYNONYM_EN])
|
||||||
|
|
||||||
# ПРОВЕРКА 3: EXACT_SYNONYM_MATCH (точное совпадение синонимов текущей записи с синонимами других)
|
# ПРОВЕРКА 3: EXACT_SYNONYM_MATCH (точное совпадение синонимов текущей записи с синонимами других)
|
||||||
# Ищем: есть ли синонимы из текущей записи в синонимах других записей?
|
# Ищем: есть ли синонимы из текущей записи в синонимах других записей?
|
||||||
@@ -188,10 +188,10 @@ def validate_for_duplicates(
|
|||||||
# Например, если текущая запись имеет синонимы=['Polydor Records', 'Vertigo France'],
|
# Например, если текущая запись имеет синонимы=['Polydor Records', 'Vertigo France'],
|
||||||
# а запись A имеет синонимы=['Vertigo France', 'Swirl'], это совпадение!
|
# а запись A имеет синонимы=['Vertigo France', 'Swirl'], это совпадение!
|
||||||
# Пользователь подтверждает - удалим конфликтующие синонимы из других записей.
|
# Пользователь подтверждает - удалим конфликтующие синонимы из других записей.
|
||||||
if KEY_SYNONYM in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM], list):
|
if KEY_SYNONYM_EN in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM_EN], list):
|
||||||
# Собираем все синонимы текущей записи с нормализацией
|
# Собираем все синонимы текущей записи с нормализацией
|
||||||
current_synonyms = [
|
current_synonyms = [
|
||||||
normalize_string(syn) for syn in metadata_dict[KEY_SYNONYM]
|
normalize_string(syn) for syn in metadata_dict[KEY_SYNONYM_EN]
|
||||||
]
|
]
|
||||||
|
|
||||||
# Удаляем дубликаты синонимов, сохраняя порядок
|
# Удаляем дубликаты синонимов, сохраняя порядок
|
||||||
@@ -215,7 +215,7 @@ def validate_for_duplicates(
|
|||||||
query_params = []
|
query_params = []
|
||||||
for normalized_synonym in current_synonyms:
|
for normalized_synonym in current_synonyms:
|
||||||
synonym_query_parts.append(
|
synonym_query_parts.append(
|
||||||
f"EXISTS (SELECT 1 FROM json_each({metadata_field_name}, '$.{KEY_SYNONYM}') WHERE LOWER(json_each.value) = %s)"
|
f"EXISTS (SELECT 1 FROM json_each({metadata_field_name}, '$.{KEY_SYNONYM_EN}') WHERE LOWER(json_each.value) = %s)"
|
||||||
)
|
)
|
||||||
query_params.append(normalized_synonym)
|
query_params.append(normalized_synonym)
|
||||||
|
|
||||||
@@ -283,7 +283,7 @@ def validate_for_duplicates(
|
|||||||
if len(word) >= effective_min_word_len:
|
if len(word) >= effective_min_word_len:
|
||||||
word_search_conditions.append(
|
word_search_conditions.append(
|
||||||
f"""EXISTS (
|
f"""EXISTS (
|
||||||
SELECT 1 FROM json_each({metadata_field_name}, '$.{KEY_SYNONYM}')
|
SELECT 1 FROM json_each({metadata_field_name}, '$.{KEY_SYNONYM_EN}')
|
||||||
WHERE LOWER(json_each.value) LIKE %s
|
WHERE LOWER(json_each.value) LIKE %s
|
||||||
)"""
|
)"""
|
||||||
)
|
)
|
||||||
@@ -343,7 +343,7 @@ def remove_conflicting_synonyms_from_duplicates(
|
|||||||
remove_conflicting_synonyms_from_duplicates(
|
remove_conflicting_synonyms_from_duplicates(
|
||||||
duplicates_queryset,
|
duplicates_queryset,
|
||||||
'j_label_metadata',
|
'j_label_metadata',
|
||||||
metadata_dict.get(KEY_SYNONYM) or [],
|
metadata_dict.get(KEY_SYNONYM_EN) or [],
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
# Нормализуем синонимы для удаления один раз
|
# Нормализуем синонимы для удаления один раз
|
||||||
@@ -354,10 +354,10 @@ def remove_conflicting_synonyms_from_duplicates(
|
|||||||
dup_metadata = getattr(duplicate_record, metadata_field_name) or {}
|
dup_metadata = getattr(duplicate_record, metadata_field_name) or {}
|
||||||
|
|
||||||
# Если в метаданных есть синонимы, удаляем те, которые совпадают с нашим списком
|
# Если в метаданных есть синонимы, удаляем те, которые совпадают с нашим списком
|
||||||
if KEY_SYNONYM in dup_metadata and isinstance(dup_metadata[KEY_SYNONYM], list):
|
if KEY_SYNONYM_EN in dup_metadata and isinstance(dup_metadata[KEY_SYNONYM_EN], list):
|
||||||
# Удаляем синонимы, которые совпадают с переданным списком
|
# Удаляем синонимы, которые совпадают с переданным списком
|
||||||
dup_metadata[KEY_SYNONYM] = [
|
dup_metadata[KEY_SYNONYM_EN] = [
|
||||||
syn for syn in dup_metadata[KEY_SYNONYM]
|
syn for syn in dup_metadata[KEY_SYNONYM_EN]
|
||||||
if normalize_string(syn) not in normalized_to_remove
|
if normalize_string(syn) not in normalized_to_remove
|
||||||
]
|
]
|
||||||
# Сохраняем обновленные метаданные
|
# Сохраняем обновленные метаданные
|
||||||
@@ -403,7 +403,7 @@ def build_search_report(
|
|||||||
search_words.update(re.split(r'\s+', main_value_normalized))
|
search_words.update(re.split(r'\s+', main_value_normalized))
|
||||||
|
|
||||||
# Собираем слова из синонимов метаданных
|
# Собираем слова из синонимов метаданных
|
||||||
metadata_synonyms = metadata_dict.get(KEY_SYNONYM) or []
|
metadata_synonyms = metadata_dict.get(KEY_SYNONYM_EN) or []
|
||||||
for synonym in metadata_synonyms:
|
for synonym in metadata_synonyms:
|
||||||
# Применяем супер-нормализацию к каждому синониму
|
# Применяем супер-нормализацию к каждому синониму
|
||||||
syn_normalized = super_normalize_string(synonym)
|
syn_normalized = super_normalize_string(synonym)
|
||||||
@@ -429,7 +429,7 @@ def build_search_report(
|
|||||||
|
|
||||||
# Получаем метаданные и синонимы
|
# Получаем метаданные и синонимы
|
||||||
dup_metadata = getattr(dup, metadata_field_name) or {}
|
dup_metadata = getattr(dup, metadata_field_name) or {}
|
||||||
dup_synonyms = dup_metadata.get(KEY_SYNONYM) or []
|
dup_synonyms = dup_metadata.get(KEY_SYNONYM_EN) or []
|
||||||
|
|
||||||
# Ищем слово в основном поле и синонимах (case-insensitive)
|
# Ищем слово в основном поле и синонимах (case-insensitive)
|
||||||
found_locations = []
|
found_locations = []
|
||||||
@@ -667,7 +667,7 @@ def validate_entity_for_admin_form(
|
|||||||
remove_conflicting_synonyms_from_duplicates(
|
remove_conflicting_synonyms_from_duplicates(
|
||||||
duplicates_queryset,
|
duplicates_queryset,
|
||||||
metadata_field_name,
|
metadata_field_name,
|
||||||
metadata_dict.get(KEY_SYNONYM) or [], # Удаляем все синонимы текущей записи
|
metadata_dict.get(KEY_SYNONYM_EN) or [], # Удаляем все синонимы текущей записи
|
||||||
)
|
)
|
||||||
# Выходим без ошибки в админку, т.к. пользователь "проверил и уверен!"
|
# Выходим без ошибки в админку, т.к. пользователь "проверил и уверен!"
|
||||||
# Конфликтующие синонимы удалены, запись сохранится нормально
|
# Конфликтующие синонимы удалены, запись сохранится нормально
|
||||||
@@ -679,7 +679,7 @@ def validate_entity_for_admin_form(
|
|||||||
# Для каждого синонима текущей записи ищем, в каких записях он есть
|
# Для каждого синонима текущей записи ищем, в каких записях он есть
|
||||||
|
|
||||||
# Собираем текущие синонимы с нормализацией
|
# Собираем текущие синонимы с нормализацией
|
||||||
current_synonyms_list = metadata_dict.get(KEY_SYNONYM) or []
|
current_synonyms_list = metadata_dict.get(KEY_SYNONYM_EN) or []
|
||||||
|
|
||||||
# Строим словарь: {нормализованный синоним: {оригинальный синоним, запись1, запись2, ...}}
|
# Строим словарь: {нормализованный синоним: {оригинальный синоним, запись1, запись2, ...}}
|
||||||
synonym_to_records = {}
|
synonym_to_records = {}
|
||||||
@@ -694,7 +694,7 @@ def validate_entity_for_admin_form(
|
|||||||
# Ищем этот синоним в метаданных других записей
|
# Ищем этот синоним в метаданных других записей
|
||||||
for dup in duplicates_queryset:
|
for dup in duplicates_queryset:
|
||||||
dup_metadata = getattr(dup, metadata_field_name) or {}
|
dup_metadata = getattr(dup, metadata_field_name) or {}
|
||||||
dup_synonyms = dup_metadata.get(KEY_SYNONYM) or []
|
dup_synonyms = dup_metadata.get(KEY_SYNONYM_EN) or []
|
||||||
|
|
||||||
# Проверяем: есть ли текущий синоним в синонимах этой записи
|
# Проверяем: есть ли текущий синоним в синонимах этой записи
|
||||||
for dup_syn in dup_synonyms:
|
for dup_syn in dup_synonyms:
|
||||||
|
|||||||
@@ -317,7 +317,8 @@ LOGGING = {
|
|||||||
SLUG_MAX_LENGTH = 60
|
SLUG_MAX_LENGTH = 60
|
||||||
|
|
||||||
# Ключи для типовых параметров в мета-полях (для TbLabel, TbSeller, TbArtist, TbMusicStyle и т.д.)
|
# Ключи для типовых параметров в мета-полях (для TbLabel, TbSeller, TbArtist, TbMusicStyle и т.д.)
|
||||||
KEY_SYNONYM = 'SYNONYM'
|
KEY_SYNONYM_EN = 'SYN_EN' # Ключ для хранения синонимов на английском языке (для поиска по синонимам) и ДЛЯ ПАРСЕРОВ
|
||||||
|
KEY_SYNONYM_RU = 'SYN_RU' # Ключ для хранения синонимов на русском языке (для представления на фронтенд)
|
||||||
|
|
||||||
# ДЛЯ ВАЛИДАЦИИ (поиска похожих исполнителей, стилей и т.д. (используется в TbLabel.matching_type, TbSeller.matching_type и т.д.)
|
# ДЛЯ ВАЛИДАЦИИ (поиска похожих исполнителей, стилей и т.д. (используется в TbLabel.matching_type, TbSeller.matching_type и т.д.)
|
||||||
VALIDATE_KEY__MATCH_TYPE = 'MATCH_TYPE'
|
VALIDATE_KEY__MATCH_TYPE = 'MATCH_TYPE'
|
||||||
|
|||||||
Reference in New Issue
Block a user