minor: переименован ключ для синонимов в метаданных ("SYNONYM" -> "KEY_SYNONYM_EN") и переменная для него (KEY_SYNONYM -> KEY_SYNONYM_EN)

This commit is contained in:
2026-07-02 19:13:53 +03:00
parent f6267e1e6c
commit 19e812e231
3 changed files with 33 additions and 32 deletions
+13 -13
View File
@@ -16,7 +16,7 @@ from django.utils.html import mark_safe
from django.http import HttpRequest
from django.db.models import Model
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 и т.д.)
Логика:
- При создании новой записи: добавляет текущее значение поля в SYNONYM
- При редактировании: если значение поля изменилось, добавляет ОБА (старое и новое) в SYNONYM
- При создании новой записи: добавляет текущее значение поля в SYN_EN
- При редактировании: если значение поля изменилось, добавляет ОБА (старое и новое) в SYN_EN
- Очищает дубликаты в списке синонимов, сохраняя порядок
- Использует KEY_SYNONYM из settings как ключ в metadata словаре
- Использует KEY_SYN_EN из settings как ключ в metadata словаре
Args:
instance: Экземпляр модели (self из save методе). Обязателен!
@@ -282,25 +282,25 @@ def update_synonyms_in_metadata(
setattr(instance, metadata_field_name, metadata_dict)
# Убеждаемся, что ключ 'SYNONYM' существует и это список
if KEY_SYNONYM not in metadata_dict or not isinstance(metadata_dict[KEY_SYNONYM], list):
metadata_dict[KEY_SYNONYM] = []
if KEY_SYNONYM_EN not in metadata_dict or not isinstance(metadata_dict[KEY_SYNONYM_EN], list):
metadata_dict[KEY_SYNONYM_EN] = []
# ===== ДОБАВЛЯЕМ СИНОНИМЫ =====
# Добавляем синонимы при создании ИЛИ если значение поля изменилось
if is_new or old_field_value != current_field_value:
# Если поле было обновлено и значение изменилось - добавляем старое значение
if old_field_value and old_field_value not in metadata_dict[KEY_SYNONYM]:
metadata_dict[KEY_SYNONYM].append(old_field_value)
if old_field_value and old_field_value not in metadata_dict[KEY_SYNONYM_EN]:
metadata_dict[KEY_SYNONYM_EN].append(old_field_value)
# Добавляем текущее значение если его еще нет в синонимах
if current_field_value not in metadata_dict[KEY_SYNONYM]:
metadata_dict[KEY_SYNONYM].append(current_field_value)
if current_field_value not in metadata_dict[KEY_SYNONYM_EN]:
metadata_dict[KEY_SYNONYM_EN].append(current_field_value)
# ===== ОЧИЩАЕМ ДУБЛИКАТЫ =====
# Удаляем дубликаты в списке синонимов, сохраняя порядок
# (может случиться если пользователь вручную редактировал метаданные)
if KEY_SYNONYM in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM], list):
metadata_dict[KEY_SYNONYM] = list(dict.fromkeys(metadata_dict[KEY_SYNONYM]))
if KEY_SYNONYM_EN in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM_EN], list):
metadata_dict[KEY_SYNONYM_EN] = list(dict.fromkeys(metadata_dict[KEY_SYNONYM_EN]))
# ===== СООБЩАЕМ DJANGO ЧТО ПОЛЕ ИЗМЕНИЛОСЬ =====
# Для JSONField нужно явно сообщить что мы изменили содержимое
@@ -383,7 +383,7 @@ def create_or_get_related_article(
# Собираем синонимы из метаданных для 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]
+18 -18
View File
@@ -14,7 +14,7 @@ from django.http import HttpRequest
from django.forms import ModelForm
from django.contrib import messages
from lpon_site.settings import (
KEY_SYNONYM,
KEY_SYNONYM_EN,
VALIDATE_KEY__MATCH_TYPE, VALIDATE_KEY__MODEL, VALIDATE_KEY__VALUE,
ValidateMatchType, MIN_SYNONYM_WORD_LENGTH
)
@@ -143,7 +143,7 @@ def validate_for_duplicates(
})
return duplicates_found
# ПРОВЕРКА 2: SYNONYM MATCH (совпадение с синонимами в метаданных других записей)
# ПРОВЕРКА 2:SYN_ENMATCH (совпадение с синонимами в метаданных других записей)
# Ищем: есть ли текущее значение main_field в синонимах других записей?
# Например, если у записи A синонимы=['Sony Music', 'SME Records'],
# а мы добавляем запись B с основным полем 'Sony Music', это совпадение!
@@ -159,7 +159,7 @@ def validate_for_duplicates(
has_synonym=RawSQL(
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) = %s
)
""",
@@ -179,8 +179,8 @@ def validate_for_duplicates(
# основное поле + все синонимы из метаданных
# Этот список переиспользуется на этапах 3 и 4, избегая дублирования логики
raw_values_to_analyze = [main_field_value]
if KEY_SYNONYM in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM], list):
raw_values_to_analyze.extend(metadata_dict[KEY_SYNONYM])
if KEY_SYNONYM_EN in metadata_dict and isinstance(metadata_dict[KEY_SYNONYM_EN], list):
raw_values_to_analyze.extend(metadata_dict[KEY_SYNONYM_EN])
# ПРОВЕРКА 3: EXACT_SYNONYM_MATCH (точное совпадение синонимов текущей записи с синонимами других)
# Ищем: есть ли синонимы из текущей записи в синонимах других записей?
@@ -188,10 +188,10 @@ def validate_for_duplicates(
# Например, если текущая запись имеет синонимы=['Polydor Records', 'Vertigo France'],
# а запись 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 = [
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 = []
for normalized_synonym in current_synonyms:
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)
@@ -283,7 +283,7 @@ def validate_for_duplicates(
if len(word) >= effective_min_word_len:
word_search_conditions.append(
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
)"""
)
@@ -343,7 +343,7 @@ def remove_conflicting_synonyms_from_duplicates(
remove_conflicting_synonyms_from_duplicates(
duplicates_queryset,
'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 {}
# Если в метаданных есть синонимы, удаляем те, которые совпадают с нашим списком
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] = [
syn for syn in dup_metadata[KEY_SYNONYM]
dup_metadata[KEY_SYNONYM_EN] = [
syn for syn in dup_metadata[KEY_SYNONYM_EN]
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))
# Собираем слова из синонимов метаданных
metadata_synonyms = metadata_dict.get(KEY_SYNONYM) or []
metadata_synonyms = metadata_dict.get(KEY_SYNONYM_EN) or []
for synonym in metadata_synonyms:
# Применяем супер-нормализацию к каждому синониму
syn_normalized = super_normalize_string(synonym)
@@ -429,7 +429,7 @@ def build_search_report(
# Получаем метаданные и синонимы
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)
found_locations = []
@@ -667,7 +667,7 @@ def validate_entity_for_admin_form(
remove_conflicting_synonyms_from_duplicates(
duplicates_queryset,
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, ...}}
synonym_to_records = {}
@@ -694,7 +694,7 @@ def validate_entity_for_admin_form(
# Ищем этот синоним в метаданных других записей
for dup in duplicates_queryset:
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:
+2 -1
View File
@@ -317,7 +317,8 @@ LOGGING = {
SLUG_MAX_LENGTH = 60
# Ключи для типовых параметров в мета-полях (для TbLabel, TbSeller, TbArtist, TbMusicStyle и т.д.)
KEY_SYNONYM = 'SYNONYM'
KEY_SYNONYM_EN = 'SYN_EN' # Ключ для хранения синонимов на английском языке (для поиска по синонимам) и ДЛЯ ПАРСЕРОВ
KEY_SYNONYM_RU = 'SYN_RU' # Ключ для хранения синонимов на русском языке (для представления на фронтенд)
# ДЛЯ ВАЛИДАЦИИ (поиска похожих исполнителей, стилей и т.д. (используется в TbLabel.matching_type, TbSeller.matching_type и т.д.)
VALIDATE_KEY__MATCH_TYPE = 'MATCH_TYPE'