fix(api): add multiple fallbacks for PhoneNumber conversion in Excel export
Проблема: На production сервере некоторые PhoneNumber объекты не конвертируются даже через str(), вызывая ValueError в openpyxl. Решение: Добавлена цепочка fallback'ов: 1. format_number() - нормальное форматирование (+7 928 826-66-50) 2. str() - если format_number() падает 3. repr() - если str() тоже не работает 4. '[invalid phone]' - если вообще ничего не работает Теперь экспорт гарантированно не упадёт на некорректных телефонах. Test: Протестировано локально на 8 сотрудниках - все работают. Production: Должно решить проблему с конкретными записями на сервере.
This commit is contained in:
parent
8f273304c3
commit
58a7c983ee
@ -2073,14 +2073,23 @@ class EmployeeViewSet(viewsets.ModelViewSet):
|
||||
# Получаем навыки
|
||||
skills = ", ".join([s.name for s in emp.skills.all()])
|
||||
|
||||
# Форматируем телефон (PhoneNumber -> строка)
|
||||
# Форматируем телефон (PhoneNumber -> строка) - БЕЗОПАСНО
|
||||
phone_str = ''
|
||||
if emp.phone_number:
|
||||
try:
|
||||
from phonenumbers import format_number, PhoneNumberFormat
|
||||
phone_str = format_number(emp.phone_number, PhoneNumberFormat.INTERNATIONAL)
|
||||
except:
|
||||
phone_str = str(emp.phone_number)
|
||||
except Exception:
|
||||
try:
|
||||
# Fallback 1: str()
|
||||
phone_str = str(emp.phone_number)
|
||||
except Exception:
|
||||
# Fallback 2: repr() как last resort
|
||||
try:
|
||||
phone_str = repr(emp.phone_number)
|
||||
except Exception:
|
||||
# Полный fallback - пустая строка
|
||||
phone_str = '[invalid phone]'
|
||||
|
||||
# Данные строки
|
||||
row_data = [
|
||||
|
||||
43
backend/test_phone_export.py
Normal file
43
backend/test_phone_export.py
Normal file
@ -0,0 +1,43 @@
|
||||
"""Тест форматирования телефонов для Excel экспорта."""
|
||||
import os
|
||||
import django
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'eusrr_backend.settings')
|
||||
django.setup()
|
||||
|
||||
from employees.models import Employee
|
||||
from phonenumbers import format_number, PhoneNumberFormat
|
||||
|
||||
print("Тестирование форматирования телефонов...\n")
|
||||
|
||||
# Получаем всех сотрудников с телефонами
|
||||
employees = Employee.objects.exclude(phone_number__isnull=True).exclude(phone_number='')
|
||||
|
||||
print(f"Найдено сотрудников с телефонами: {employees.count()}\n")
|
||||
|
||||
errors = []
|
||||
for emp in employees:
|
||||
phone_str = ''
|
||||
if emp.phone_number:
|
||||
try:
|
||||
# Пытаемся форматировать
|
||||
phone_str = format_number(emp.phone_number, PhoneNumberFormat.INTERNATIONAL)
|
||||
print(f"✓ {emp.id}: {emp.last_name} {emp.first_name} - {phone_str}")
|
||||
except Exception as e:
|
||||
# Fallback на str()
|
||||
try:
|
||||
phone_str = str(emp.phone_number)
|
||||
print(f"⚠ {emp.id}: {emp.last_name} {emp.first_name} - {phone_str} (fallback)")
|
||||
except Exception as e2:
|
||||
phone_str = ''
|
||||
error_msg = f"✗ {emp.id}: {emp.last_name} {emp.first_name} - ERROR: {type(emp.phone_number).__name__} - {e2}"
|
||||
print(error_msg)
|
||||
errors.append(error_msg)
|
||||
|
||||
print(f"\n\nВсего ошибок: {len(errors)}")
|
||||
if errors:
|
||||
print("\nПроблемные записи:")
|
||||
for err in errors:
|
||||
print(err)
|
||||
else:
|
||||
print("Все телефоны успешно конвертируются!")
|
||||
Loading…
x
Reference in New Issue
Block a user