fix(): fix models for get flags
This commit is contained in:
1 parent
77ebb0e3a8
commit
81ff26fdb8
4 files changed
+65
-38
No files matched your search
+36
-27
@@ -1,6 +1,7 @@
|
|||||||
from flask import jsonify, request
|
from flask import jsonify, request
|
||||||
from db.handlers.product_handler import get_products_with_filters, get_product_by_id
|
from db.handlers.product_handler import get_products_with_filters, get_product_by_id
|
||||||
from flask import Blueprint
|
from flask import Blueprint
|
||||||
|
import re
|
||||||
|
|
||||||
api_product = Blueprint('api_product', __name__, url_prefix='/products')
|
api_product = Blueprint('api_product', __name__, url_prefix='/products')
|
||||||
|
|
||||||
@@ -15,6 +16,23 @@ def clean_filter_value(value):
|
|||||||
return cleaned
|
return cleaned
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def parse_size(size_str):
|
||||||
|
"""
|
||||||
|
Парсит строку размера вида "110х2,2х500" и возвращает словарь с ключами diameter, wall_thickness, length.
|
||||||
|
"""
|
||||||
|
if not size_str:
|
||||||
|
return {}
|
||||||
|
# Заменяем запятую на точку для толщины
|
||||||
|
normalized = size_str.replace(',', '.')
|
||||||
|
match = re.match(r'(\d+)х([\d\.]+)х(\d+)', normalized)
|
||||||
|
if match:
|
||||||
|
return {
|
||||||
|
'diameter': int(match.group(1)),
|
||||||
|
'wall_thickness': float(match.group(2)),
|
||||||
|
'length': int(match.group(3))
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
|
||||||
@api_product.route('/', methods=['GET'], strict_slashes=False)
|
@api_product.route('/', methods=['GET'], strict_slashes=False)
|
||||||
def get_products():
|
def get_products():
|
||||||
try:
|
try:
|
||||||
@@ -30,42 +48,33 @@ def get_products():
|
|||||||
if limit < 1 or limit > 100:
|
if limit < 1 or limit > 100:
|
||||||
limit = 9
|
limit = 9
|
||||||
|
|
||||||
# ✅ ИСПРАВЛЕННЫЙ МАППИНГ
|
|
||||||
filter_mapping = {
|
|
||||||
'attr_1': 'diameter',
|
|
||||||
'attr_2': 'length',
|
|
||||||
'attr_3': 'wall_thickness', # (опционально) тоже толщина
|
|
||||||
'attr_4': 'color',
|
|
||||||
'attr_5': 'stiffness_class', # SN2, SN4
|
|
||||||
'attr_6': 'wall_thickness', # <- теперь attr_6 ищет толщину стенки
|
|
||||||
'attr_7': 'angle',
|
|
||||||
'attr_8': 'fitting_type',
|
|
||||||
}
|
|
||||||
|
|
||||||
filters = {}
|
filters = {}
|
||||||
excluded_params = {'categoryId', 'page', 'limit'}
|
excluded_params = {'categoryId', 'page', 'limit'}
|
||||||
|
|
||||||
|
# Обрабатываем все параметры запроса
|
||||||
for key, value in request.args.items():
|
for key, value in request.args.items():
|
||||||
if key in excluded_params:
|
if key in excluded_params:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
real_key = filter_mapping.get(key, key)
|
|
||||||
|
|
||||||
if ',' in value:
|
|
||||||
parts = value.split(',')
|
|
||||||
cleaned_parts = []
|
|
||||||
for part in parts:
|
|
||||||
cleaned = clean_filter_value(part)
|
|
||||||
if cleaned is not None:
|
|
||||||
cleaned_parts.append(cleaned)
|
|
||||||
if cleaned_parts:
|
|
||||||
filters[real_key] = cleaned_parts
|
|
||||||
else:
|
|
||||||
cleaned = clean_filter_value(value)
|
cleaned = clean_filter_value(value)
|
||||||
if cleaned is not None:
|
if cleaned is None:
|
||||||
filters[real_key] = cleaned
|
continue
|
||||||
|
|
||||||
|
# Специальная обработка параметра size
|
||||||
|
if key == 'size':
|
||||||
|
size_parts = parse_size(cleaned)
|
||||||
|
for size_key, size_val in size_parts.items():
|
||||||
|
# Добавляем как одиночные фильтры (без списка)
|
||||||
|
filters[size_key] = size_val
|
||||||
|
else:
|
||||||
|
# Остальные фильтры (color, stiffness_class, и т.д.)
|
||||||
|
if ',' in cleaned:
|
||||||
|
parts = [p.strip() for p in cleaned.split(',') if p.strip()]
|
||||||
|
if parts:
|
||||||
|
filters[key] = parts
|
||||||
|
else:
|
||||||
|
filters[key] = cleaned
|
||||||
|
|
||||||
# Отладочный вывод (убедитесь, что здесь видно правильный ключ)
|
|
||||||
print("=== FINAL FILTERS ===", filters)
|
print("=== FINAL FILTERS ===", filters)
|
||||||
|
|
||||||
result = get_products_with_filters(
|
result = get_products_with_filters(
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ def get_all_categories_with_attributes(db_name: str = 'pipe_store.db') -> List[D
|
|||||||
attributes.append({
|
attributes.append({
|
||||||
"id": filter_id,
|
"id": filter_id,
|
||||||
"name": filter_name,
|
"name": filter_name,
|
||||||
|
"flag": filter_key, # добавлено поле flag
|
||||||
"vals": vals
|
"vals": vals
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ def get_all_categories_with_attributes(db_name: str = 'pipe_store.db') -> List[D
|
|||||||
"id": category_id,
|
"id": category_id,
|
||||||
"name": cat_row['name'],
|
"name": cat_row['name'],
|
||||||
"image": cat_row['image_path'] or f"/images/categories/{cat_row['name'].lower().replace(' ', '_')}.jpg",
|
"image": cat_row['image_path'] or f"/images/categories/{cat_row['name'].lower().replace(' ', '_')}.jpg",
|
||||||
"atributes": attributes
|
"attributes": attributes # исправлено atributes → attributes
|
||||||
})
|
})
|
||||||
|
|
||||||
return categories
|
return categories
|
||||||
|
|||||||
@@ -90,20 +90,31 @@ def get_products_with_filters(
|
|||||||
# 5. Формируем ответ
|
# 5. Формируем ответ
|
||||||
items = []
|
items = []
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
# Вычисляем size
|
||||||
|
size = None
|
||||||
|
if row['diameter'] and row['wall_thickness'] and row['length'] and row['length'] > 0:
|
||||||
|
size = f"{row['diameter']}x{row['wall_thickness']}x{row['length']}"
|
||||||
|
|
||||||
|
# Количество в упаковке
|
||||||
|
amount = get_pack_amount(row['id'], row['diameter'])
|
||||||
|
|
||||||
items.append({
|
items.append({
|
||||||
"id": row['id'],
|
"id": row['id'],
|
||||||
"name": row['name'],
|
"name": row['name'],
|
||||||
"full_name": row['full_name'],
|
|
||||||
"description": row['description'],
|
"description": row['description'],
|
||||||
"categoryId": row['category_id'],
|
"categoryId": row['category_id'],
|
||||||
"images": [row['image_path']] if row['image_path'] else ["/images/products/default.jpg"],
|
"images": [row['image_path']] if row['image_path'] else ["/images/products/default.jpg"],
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"diameter": row['diameter'],
|
|
||||||
"length": row['length'],
|
|
||||||
"wall_thickness": row['wall_thickness'],
|
|
||||||
"color": row['color'],
|
"color": row['color'],
|
||||||
|
"amount": amount,
|
||||||
|
"size": size,
|
||||||
|
"diameter": str(row['diameter']) if row['diameter'] else None,
|
||||||
|
"wall_thickness": str(row['wall_thickness']) if row['wall_thickness'] else None,
|
||||||
|
"length": str(row['length']) if row['length'] and row['length'] > 0 else None,
|
||||||
|
"stiffness_class": row['stiffness_class'],
|
||||||
"application_type": row['application_type']
|
"application_type": row['application_type']
|
||||||
}
|
},
|
||||||
|
"inStock": True
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -157,9 +168,17 @@ def get_product_by_id(product_id: int, db_name: str = 'pipe_store.db') -> Option
|
|||||||
|
|
||||||
full_description = generate_full_description(row)
|
full_description = generate_full_description(row)
|
||||||
|
|
||||||
|
# Вычисляем size и amount
|
||||||
|
size = None
|
||||||
|
if row['diameter'] and row['wall_thickness'] and row['length'] and row['length'] > 0:
|
||||||
|
size = f"{row['diameter']}x{row['wall_thickness']}x{row['length']}"
|
||||||
|
amount = get_pack_amount(product_id, row['diameter'])
|
||||||
|
|
||||||
# Формируем атрибуты
|
# Формируем атрибуты
|
||||||
attributes = {
|
attributes = {
|
||||||
"color": row['color'],
|
"color": row['color'],
|
||||||
|
"amount": amount,
|
||||||
|
"size": size,
|
||||||
"diameter": str(row['diameter']) if row['diameter'] else None,
|
"diameter": str(row['diameter']) if row['diameter'] else None,
|
||||||
"wall_thickness": str(row['wall_thickness']) if row['wall_thickness'] else None,
|
"wall_thickness": str(row['wall_thickness']) if row['wall_thickness'] else None,
|
||||||
"length": str(row['length']) if row['length'] and row['length'] > 0 else None,
|
"length": str(row['length']) if row['length'] and row['length'] > 0 else None,
|
||||||
@@ -167,9 +186,6 @@ def get_product_by_id(product_id: int, db_name: str = 'pipe_store.db') -> Option
|
|||||||
"application_type": row['application_type'],
|
"application_type": row['application_type'],
|
||||||
}
|
}
|
||||||
|
|
||||||
if all([row['diameter'], row['wall_thickness'], row['length'] and row['length'] > 0]):
|
|
||||||
attributes["size"] = f"{row['diameter']}x{row['wall_thickness']}x{row['length']}"
|
|
||||||
|
|
||||||
# Добавляем дополнительные атрибуты
|
# Добавляем дополнительные атрибуты
|
||||||
attributes.update(extra_attributes)
|
attributes.update(extra_attributes)
|
||||||
|
|
||||||
@@ -178,7 +194,7 @@ def get_product_by_id(product_id: int, db_name: str = 'pipe_store.db') -> Option
|
|||||||
"name": row['name'],
|
"name": row['name'],
|
||||||
"full_name": row['full_name'],
|
"full_name": row['full_name'],
|
||||||
"description": full_description,
|
"description": full_description,
|
||||||
"price": None, # Цена не хранится в БД
|
"price": None,
|
||||||
"categoryId": row['category_id'],
|
"categoryId": row['category_id'],
|
||||||
"images": images,
|
"images": images,
|
||||||
"attributes": attributes,
|
"attributes": attributes,
|
||||||
|
|||||||
+2
-1
@@ -8,13 +8,14 @@ class AttributeValue(BaseModel):
|
|||||||
class Attribute(BaseModel):
|
class Attribute(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
|
flag: str # добавлено поле flag
|
||||||
vals: List[AttributeValue]
|
vals: List[AttributeValue]
|
||||||
|
|
||||||
class Category(BaseModel):
|
class Category(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
name: str
|
name: str
|
||||||
image: Optional[str] = None
|
image: Optional[str] = None
|
||||||
atributes: List[Attribute] = []
|
attributes: List[Attribute] = [] # исправлено atributes → attributes
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
from_attributes = True
|
from_attributes = True
|
||||||
Reference in new issue
Block a user