diff --git a/smartsoltech/static/assets/css/service_request_modal.css b/smartsoltech/static/assets/css/service_request_modal.css new file mode 100644 index 0000000..ed8b3dc --- /dev/null +++ b/smartsoltech/static/assets/css/service_request_modal.css @@ -0,0 +1,27 @@ + /* Добавляем стили для анимации появления модального окна */ + #serviceModal { + display: none; + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.4); + } + + .modal-content { + position: relative; + background-color: #fefefe; + margin: auto; + padding: 20px; + border: 1px solid #888; + width: 80%; + max-width: 600px; + transform: scale(0); + transition: transform 0.5s ease; + } + + .modal.show .modal-content { + transform: scale(1); + } \ No newline at end of file diff --git a/smartsoltech/static/assets/js/modal-init.js b/smartsoltech/static/assets/js/modal-init.js index cc06919..9da3b06 100644 --- a/smartsoltech/static/assets/js/modal-init.js +++ b/smartsoltech/static/assets/js/modal-init.js @@ -13,3 +13,98 @@ document.addEventListener("DOMContentLoaded", function () { }); } }); + +document.addEventListener('DOMContentLoaded', function () { + const generateQrButton = document.getElementById('generateQrButton'); + + if (generateQrButton) { + generateQrButton.addEventListener('click', function () { + const clientEmail = document.getElementById('clientEmail').value; + const clientPhone = document.getElementById('clientPhone').value; + const clientName = document.getElementById('clientName').value; + const description = document.getElementById('description').value; + const serviceId = generateQrButton.getAttribute('data-service-id'); + + // Проверка заполненности полей + if (!clientEmail || !clientPhone || !clientName || !description || !serviceId) { + alert('Все поля должны быть заполнены.'); + return; + } + + // Получение CSRF токена из cookies + function getCookie(name) { + let cookieValue = null; + if (document.cookie && document.cookie !== '') { + const cookies = document.cookie.split(';'); + for (let i = 0; i < cookies.length; i++) { + const cookie = cookies[i].trim(); + if (cookie.substring(0, name.length + 1) === (name + '=')) { + cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); + break; + } + } + } + return cookieValue; + } + + const csrftoken = getCookie('csrftoken'); + + // Отправка POST запроса на создание заявки + fetch('/service/create_request/', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken + }, + body: JSON.stringify({ + client_email: clientEmail, + client_phone: clientPhone, + client_name: clientName, + service_id: serviceId, + description: description + }) + }) + .then(response => { + if (!response.ok) { + throw new Error('Ошибка при создании заявки'); + } + return response.json(); + }) + .then(data => { + if (data.status === 'success') { + alert(data.message); + } else if (data.status === 'existing_request') { + alert(data.message); + } else { + alert('Неизвестная ошибка. Пожалуйста, попробуйте снова.'); + } + }) + .catch(error => { + console.error('Ошибка при создании заявки:', error); + }); + }); + } +}); + +function checkVerificationStatus(serviceRequestId, interval) { + fetch(`/service/request_status/${serviceRequestId}/`) + .then(response => { + if (!response.ok) { + throw new Error('Ошибка при проверке статуса заявки'); + } + return response.json(); + }) + .then(data => { + if (data.is_verified) { + // Закрываем форму и показываем окно подтверждения + document.getElementById('serviceModal').style.display = 'none'; + document.getElementById('confirmationModal').style.display = 'block'; + + // Останавливаем интервал проверки статуса + clearInterval(interval); + } + }) + .catch(error => { + console.error('Ошибка при проверке статуса заявки:', error); + }); +} \ No newline at end of file diff --git a/smartsoltech/static/qr_codes/request_334.png b/smartsoltech/static/qr_codes/request_334.png new file mode 100644 index 0000000..80962be Binary files /dev/null and b/smartsoltech/static/qr_codes/request_334.png differ diff --git a/smartsoltech/static/qr_codes/request_335.png b/smartsoltech/static/qr_codes/request_335.png new file mode 100644 index 0000000..41f785b Binary files /dev/null and b/smartsoltech/static/qr_codes/request_335.png differ diff --git a/smartsoltech/static/qr_codes/request_336.png b/smartsoltech/static/qr_codes/request_336.png new file mode 100644 index 0000000..7720724 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_336.png differ diff --git a/smartsoltech/static/qr_codes/request_337.png b/smartsoltech/static/qr_codes/request_337.png new file mode 100644 index 0000000..bb32aee Binary files /dev/null and b/smartsoltech/static/qr_codes/request_337.png differ diff --git a/smartsoltech/static/qr_codes/request_338.png b/smartsoltech/static/qr_codes/request_338.png new file mode 100644 index 0000000..835ac93 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_338.png differ diff --git a/smartsoltech/static/qr_codes/request_339.png b/smartsoltech/static/qr_codes/request_339.png new file mode 100644 index 0000000..7cbbe1a Binary files /dev/null and b/smartsoltech/static/qr_codes/request_339.png differ diff --git a/smartsoltech/static/qr_codes/request_340.png b/smartsoltech/static/qr_codes/request_340.png new file mode 100644 index 0000000..9471168 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_340.png differ diff --git a/smartsoltech/static/qr_codes/request_341.png b/smartsoltech/static/qr_codes/request_341.png new file mode 100644 index 0000000..612b539 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_341.png differ diff --git a/smartsoltech/static/qr_codes/request_342.png b/smartsoltech/static/qr_codes/request_342.png new file mode 100644 index 0000000..0f9e336 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_342.png differ diff --git a/smartsoltech/static/qr_codes/request_343.png b/smartsoltech/static/qr_codes/request_343.png new file mode 100644 index 0000000..7143133 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_343.png differ diff --git a/smartsoltech/static/qr_codes/request_344.png b/smartsoltech/static/qr_codes/request_344.png new file mode 100644 index 0000000..99294ad Binary files /dev/null and b/smartsoltech/static/qr_codes/request_344.png differ diff --git a/smartsoltech/static/qr_codes/request_345.png b/smartsoltech/static/qr_codes/request_345.png new file mode 100644 index 0000000..3fb78f3 Binary files /dev/null and b/smartsoltech/static/qr_codes/request_345.png differ diff --git a/smartsoltech/static/qr_codes/request_346.png b/smartsoltech/static/qr_codes/request_346.png new file mode 100644 index 0000000..54650fc Binary files /dev/null and b/smartsoltech/static/qr_codes/request_346.png differ diff --git a/smartsoltech/web/templates/web/modal_order_form.html b/smartsoltech/web/templates/web/modal_order_form.html index 69fe28d..01c47ee 100644 --- a/smartsoltech/web/templates/web/modal_order_form.html +++ b/smartsoltech/web/templates/web/modal_order_form.html @@ -1,3 +1,4 @@ +{% load static %} @@ -57,26 +58,29 @@ @@ -88,140 +92,7 @@ - - + diff --git a/smartsoltech/web/templates/web/service_detail.html b/smartsoltech/web/templates/web/service_detail.html index a4477ae..c0874f0 100644 --- a/smartsoltech/web/templates/web/service_detail.html +++ b/smartsoltech/web/templates/web/service_detail.html @@ -1,4 +1,3 @@ - {% extends 'web/base.html' %} {% load static %} {% block title %}Услуга - {{ service.name }}{% endblock %} @@ -14,16 +13,15 @@

{{ service.name }}

{{ service.description }}

- + - -
{% include "web/modal_order_form.html" %} +
@@ -80,17 +78,174 @@
+ + + -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/smartsoltech/web/urls.py b/smartsoltech/web/urls.py index d8e3740..2ad5386 100644 --- a/smartsoltech/web/urls.py +++ b/smartsoltech/web/urls.py @@ -22,6 +22,7 @@ urlpatterns = [ path('client/orders/', views.client_orders, name='client_orders'), path('order//', views.order_detail, name='order_detail'), path('service/send_telegram_notification/', views.send_telegram_notification, name='send_telegram_notification'), + path('service/create_request/', views.create_service_request_basic, name='create_service_request_basic'), ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/smartsoltech/web/views.py b/smartsoltech/web/views.py index e62e37a..4ef5690 100644 --- a/smartsoltech/web/views.py +++ b/smartsoltech/web/views.py @@ -20,7 +20,9 @@ import hmac import hashlib import json from django.views.decorators.csrf import csrf_exempt +import logging +logger = logging.getLogger(__name__) # sens try: bot = TelegramBot() @@ -64,215 +66,290 @@ def services_view(request): def about_view(request): return render(request, 'web/about.html') -# def create_service_request(request, service_id): -# service = get_object_or_404(Service, pk=service_id) -# if request.method == 'POST': -# client_name = request.POST.get('client_name') -# client_email = request.POST.get('client_email') -# client_phone = request.POST.get('client_phone') -# description = request.POST.get('description') -# chat_id = request.POST.get('chat_id') -# token = uuid.uuid4().hex - -# # Создаем заявку -# service_request = ServiceRequest.objects.create( -# service=service, -# client_name=client_name, -# client_email=client_email, -# client_phone=client_phone, -# chat_id=chat_id, -# token=token -# ) - -# # Генерация уникальных данных для пользователя -# username = f"{client_email.split('@')[0]}_{get_random_string(5)}" -# password = get_random_string(8) - -# # Создание пользователя -# user = User.objects.create_user(username=username, password=password) -# user.first_name = client_name.split()[0] if client_name else "" -# user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else "" -# user.email = client_email -# user.save() - -# # Создание клиента и привязка к пользователю -# client, created = Client.objects.get_or_create( -# email=client_email, -# defaults={ -# 'user': user, -# 'first_name': user.first_name, -# 'last_name': user.last_name, -# 'phone_number': client_phone, -# 'chat_id': chat_id, -# } -# ) - -# # Создание заказа на основе заявки -# order = Order.objects.create( -# service_request=service_request, -# client=client, -# service=service, -# message=description, -# status="pending" -# ) - -# # Отправка сообщения в Telegram -# if chat_id: -# bot.send_telegram_message(client.id, service_request.id, "Ваши данные для входа на сайт.", order.id) - -# return redirect(reverse('order_detail', args=[order.pk])) - -# return render(request, 'web/create_service_request.html', {'service': service}) - def create_service_request(request, service_id): - service = get_object_or_404(Service, pk=service_id) if request.method == 'POST': - # Извлечение данных формы - client_email = request.POST.get('client_email') - client_phone = request.POST.get('client_phone') - description = request.POST.get('description') - chat_id = request.POST.get('client_chat_id') - client_name = request.POST.get('client_name') + try: + # Извлечение данных из запроса + data = json.loads(request.body) + client_email = data.get('client_email') + client_phone = data.get('client_phone') + client_name = data.get('client_name') - # Проверка на наличие существующей заявки - service_request = get_object_or_404(ServiceRequest, chat_id=chat_id) + # Проверка на наличие всех необходимых данных + if not all([client_email, client_phone, client_name]): + return JsonResponse({'status': 'error', 'message': 'Все поля должны быть заполнены'}, status=400) - # Обновление данных заявки - service_request.client_email = client_email - service_request.client_phone = client_phone - service_request.message = description - service_request.save() + # Получение услуги + service = get_object_or_404(Service, pk=service_id) - # Создание клиента и пользователя, если необходимо - user, _ = User.objects.get_or_create( - username=f"{client_email.split('@')[0]}_{get_random_string(5)}", - defaults={"email": client_email} - ) - user.first_name = client_name.split()[0] if client_name else "" - user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else "" - user.save() + # Создаем или получаем клиента + client, created = Client.objects.get_or_create( + email=client_email, + defaults={ + 'first_name': client_name.split()[0] if client_name else "", + 'last_name': client_name.split()[-1] if len(client_name.split()) > 1 else "", + 'phone_number': client_phone, + } + ) - client, _ = Client.objects.get_or_create( - email=client_email, - defaults={ - 'user': user, - 'first_name': user.first_name, - 'last_name': user.last_name, - 'phone_number': client_phone, - 'chat_id': chat_id, - } - ) + # Обновляем данные клиента, если он уже существовал + if not created: + client.first_name = client_name.split()[0] + client.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else "" + client.phone_number = client_phone + client.save() - # Создание заказа, связанного с заявкой - order = Order.objects.create( - service_request=service_request, - client=client, - service=service_request.service, - message=description, - status="pending" - ) + # Проверяем, есть ли у клиента уже активная заявка + existing_requests = ServiceRequest.objects.filter(client=client, service=service, chat_id__isnull=True) + if existing_requests.exists(): + return JsonResponse({ + 'status': 'existing_request', + 'message': 'У вас уже есть активная заявка на данную услугу. Пожалуйста, проверьте ваш Telegram для завершения процесса.' + }) - # Отправка уведомления в Telegram - bot.send_telegram_message( - client.id, - service_request.id, - f"Ваш заказ на услугу '{service_request.service.name}' был успешно создан.", - order.id - ) + # Создание новой заявки на услугу + token = uuid.uuid4().hex + service_request = ServiceRequest.objects.create( + service=service, + client=client, + token=token + ) - return redirect(reverse('order_detail', args=[order.pk])) + return JsonResponse({ + 'status': 'success', + 'message': 'Заявка успешно создана. Пожалуйста, проверьте ваш Telegram для подтверждения.', + 'service_request_id': service_request.id, + }) - return render(request, 'web/create_service_request.html', {'service': service}) + except json.JSONDecodeError: + return JsonResponse({'status': 'error', 'message': 'Неверный формат данных'}, status=400) + return JsonResponse({'status': 'error', 'message': 'Метод запроса должен быть POST'}, status=405) +def create_service_request_basic(request): + if request.method == 'POST': + try: + # Извлечение данных из тела запроса + data = json.loads(request.body) + client_email = data.get('client_email') + client_phone = data.get('client_phone') + client_name = data.get('client_name') + service_id = data.get('service_id') + description = data.get('description') + + # Проверка на наличие всех необходимых данных + if not all([client_email, client_phone, client_name, service_id, description]): + return JsonResponse({'status': 'error', 'message': 'Все поля должны быть заполнены'}, status=400) + + # Получаем услугу по ID + service = get_object_or_404(Service, pk=service_id) + + # Проверка на существование активной заявки для клиента на данную услугу + existing_requests = ServiceRequest.objects.filter(client__email=client_email, service=service, chat_id__isnull=True) + if existing_requests.exists(): + return JsonResponse({ + 'status': 'existing_request', + 'message': 'У вас уже есть активная заявка на данную услугу. Пожалуйста, проверьте ваш Telegram для завершения процесса.' + }) + + # Создаем или получаем клиента + user, created = User.objects.get_or_create( + username=f"{client_email.split('@')[0]}_{get_random_string(5)}", + defaults={"email": client_email} + ) + + # Обновляем данные пользователя, если он уже существовал + user.first_name = client_name.split()[0] if client_name else "" + user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else "" + user.save() + + # Создаем или получаем объект клиента + client, _ = Client.objects.get_or_create( + email=client_email, + defaults={ + 'user': user, + 'first_name': user.first_name, + 'last_name': user.last_name, + 'phone_number': client_phone, + } + ) + + # Создаем заявку на услугу + token = uuid.uuid4().hex + service_request = ServiceRequest.objects.create( + service=service, + client=client, + token=token + ) + + # Создаем заказ на основе заявки + order = Order.objects.create( + service_request=service_request, + client=client, + service=service, + message=description, + status="pending" + ) + + # Отправляем уведомление в Telegram, если chat_id у клиента заполнен + if client.chat_id: + # Предполагается, что bot.send_telegram_message() уже настроен + bot.send_telegram_message( + client.chat_id, + f"Ваш заказ на услугу '{service.name}' был успешно создан. Пожалуйста, завершите процесс регистрации в Telegram." + ) + + return JsonResponse({ + 'status': 'success', + 'message': 'Заявка успешно создана. Пожалуйста, проверьте ваш Telegram для подтверждения.', + 'service_request_id': service_request.id, + }) + + except json.JSONDecodeError: + return JsonResponse({'status': 'error', 'message': 'Неверный формат данных'}, status=400) + except Exception as e: + return JsonResponse({'status': 'error', 'message': str(e)}, status=500) + + return JsonResponse({'status': 'error', 'message': 'Метод запроса должен быть POST'}, status=405) def generate_qr_code(request, service_id): if request.method == 'POST': - client_email = request.POST.get('client_email') - client_phone = request.POST.get('client_phone') - client_name = request.POST.get('client_name') + try: + data = json.loads(request.body) + client_email = data.get('client_email') + client_phone = data.get('client_phone') + client_name = data.get('client_name') + + # Проверка на наличие всех необходимых данных + if not all([client_email, client_phone, client_name]): + logger.error("Не все поля заполнены.") + return JsonResponse({'error': 'Все поля должны быть заполнены'}, status=400) + + except json.JSONDecodeError as e: + logger.error(f"Ошибка JSONDecodeError: {str(e)}") + return JsonResponse({'error': 'Неверный формат данных'}, status=400) # Создание или получение клиента - user, _ = User.objects.get_or_create( - username=f"{client_email.split('@')[0]}_{get_random_string(5)}", - defaults={"email": client_email} - ) - user.first_name = client_name.split()[0] if client_name else "" - user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else "" - user.save() + try: + user, created = User.objects.get_or_create( + username=f"{client_email.split('@')[0]}_{get_random_string(5)}", + defaults={"email": client_email} + ) + user.first_name = client_name.split()[0] if client_name else "" + user.last_name = client_name.split()[-1] if len(client_name.split()) > 1 else "" + user.save() - client, _ = Client.objects.get_or_create( - email=client_email, - defaults={ - 'user': user, - 'first_name': user.first_name, - 'last_name': user.last_name, - 'phone_number': client_phone - } - ) + client, _ = Client.objects.get_or_create( + email=client_email, + defaults={ + 'user': user, + 'first_name': user.first_name, + 'last_name': user.last_name, + 'phone_number': client_phone + } + ) + except Exception as e: + logger.error(f"Ошибка при создании или получении клиента: {str(e)}") + return JsonResponse({'error': f'Ошибка при создании клиента: {str(e)}'}, status=500) # Создание новой заявки на услугу - service = get_object_or_404(Service, pk=service_id) - token = uuid.uuid4().hex + try: + service = get_object_or_404(Service, pk=service_id) + token = uuid.uuid4().hex - service_request = ServiceRequest.objects.create( - service=service, - client=client, - token=token - ) + service_request = ServiceRequest.objects.create( + service=service, + client=client, + token=token + ) + except Exception as e: + logger.error(f"Ошибка при создании заявки: {str(e)}") + return JsonResponse({'error': f'Ошибка при создании заявки: {str(e)}'}, status=500) # Генерация ссылки для регистрации в Telegram - telegram_settings = get_object_or_404(TelegramSettings, pk=1) - registration_link = f'https://t.me/{telegram_settings.bot_name}?start=request_{service_request.id}_token_{urlsafe_base64_encode(force_bytes(token))}' + try: + telegram_settings = get_object_or_404(TelegramSettings, pk=1) + registration_link = f'https://t.me/{telegram_settings.bot_name}?start=request_{service_request.id}_token_{urlsafe_base64_encode(force_bytes(token))}' + except TelegramSettings.DoesNotExist: + logger.error("Не удалось получить настройки Telegram.") + return JsonResponse({'error': 'Не удалось получить настройки Telegram'}, status=500) # Генерация QR-кода - qr = qrcode.make(registration_link) - qr_code_dir = os.path.join(settings.STATICFILES_DIRS[0], 'qr_codes') - qr_code_path = os.path.join(qr_code_dir, f"request_{service_request.id}.png") - external_qr_link = f'static/qr_codes/request_{service_request.id}.png' + try: + qr = qrcode.make(registration_link) + qr_code_dir = os.path.join(settings.STATICFILES_DIRS[0], 'qr_codes') + qr_code_path = os.path.join(qr_code_dir, f"request_{service_request.id}.png") + external_qr_link = f'static/qr_codes/request_{service_request.id}.png' - if not os.path.exists(qr_code_dir): - os.makedirs(qr_code_dir) + if not os.path.exists(qr_code_dir): + os.makedirs(qr_code_dir) - qr.save(qr_code_path) + qr.save(qr_code_path) + except Exception as e: + logger.error(f"Ошибка при генерации QR-кода: {str(e)}") + return JsonResponse({'error': f'Ошибка при генерации QR-кода: {str(e)}'}, status=500) + # Возвращаем ответ, включающий все необходимые данные return JsonResponse({ 'registration_link': registration_link, 'qr_code_url': f"/{external_qr_link}", - 'service_request_id': service_request.id + 'service_request_id': service_request.id, + 'client_email': client_email, + 'client_phone': client_phone, + 'client_name': client_name }) else: + logger.error("Неправильный метод запроса") return JsonResponse({'error': 'Метод запроса должен быть POST'}, status=405) + def complete_registration(request, request_id): # Завершение регистрации по идентификатору заявки service_request = get_object_or_404(ServiceRequest, pk=request_id) if request.method == 'POST': - client_name = request.POST.get('client_name', service_request.client_name) - client_email = request.POST.get('client_email', service_request.client_email) - client_phone = request.POST.get('client_phone', service_request.client_phone) + client_email = request.POST.get('client_email', service_request.client.email) + client_phone = request.POST.get('client_phone', service_request.client.phone_number) chat_id = request.POST.get('chat_id', service_request.chat_id) - # Обновляем данные заявки - service_request.client_name = client_name - service_request.client_email = client_email - service_request.client_phone = client_phone + # Проверка корректности данных + if not all([client_email, client_phone, chat_id]): + return JsonResponse({'status': 'error', 'message': 'Все поля должны быть заполнены.'}, status=400) + + # Обновляем данные клиента + client = service_request.client + client.email = client_email + client.phone_number = client_phone + client.save() + + # Обновляем заявку service_request.chat_id = chat_id service_request.save() - return redirect('home') + return JsonResponse({'status': 'success', 'message': 'Регистрация успешно завершена.'}) + + return render(request, 'web/complete_registration.html', {'service_request': service_request}) + return render(request, 'web/complete_registration.html', {'service_request': service_request}) def request_status(request, service_id): - # Проверяем статус заявки на услугу - service_request = get_object_or_404(ServiceRequest, pk=service_id) - is_verified = service_request.client_name != '' and service_request.chat_id != '' + try: + # Получаем заявку на услугу по ID + service_request = get_object_or_404(ServiceRequest, pk=service_id) + + # Получаем объект клиента через связанное поле client + client = service_request.client - return JsonResponse({ - 'is_verified': is_verified, - 'client_name': service_request.client_name, - 'client_chat_id' : service_request.chat_id, -}) + # Проверка, что клиент существует и его Telegram chat_id заполнен + is_verified = bool(client and client.chat_id) + + # Возвращаем данные клиента и статус верификации + return JsonResponse({ + 'is_verified': is_verified, + 'client_name': client.first_name if client else "Неизвестно", + 'client_chat_id': client.chat_id if client else None, + }) + except Exception as e: + return JsonResponse({'error': str(e)}, status=500) def complete_registration_basic(request): # Базовая регистрация без идентификатора заявки @@ -355,8 +432,9 @@ def send_telegram_notification(request): if not chat_id: return JsonResponse({'error': 'Нет chat_id для отправки сообщения'}, status=400) + # Составление и отправка сообщения message = ( - f"Здравствуйте, {service_request.client_name}!\n" + f"Здравствуйте, {service_request.client.first_name}!\n" f"Ваша заявка на услугу '{service_request.service.name}' успешно зарегистрирована." ) @@ -364,6 +442,8 @@ def send_telegram_notification(request): return JsonResponse({'status': 'Уведомление успешно отправлено в Telegram'}) + except json.JSONDecodeError: + return JsonResponse({'error': 'Неверный формат данных'}, status=400) except Exception as e: return JsonResponse({'error': str(e)}, status=500)