2025-08-03 10:28:43 +09:00
|
|
|
from django.shortcuts import render, redirect
|
|
|
|
|
from django.http import HttpResponse, JsonResponse
|
|
|
|
|
from urllib.parse import unquote
|
|
|
|
|
from .models import Person
|
|
|
|
|
from django.db import models
|
|
|
|
|
from django.contrib.auth.decorators import login_required
|
|
|
|
|
from .forms import PersonForm, Step1PhoneForm, Step2AccountForm
|
|
|
|
|
from .models import Person
|
|
|
|
|
from django.shortcuts import get_object_or_404
|
|
|
|
|
from django.db.models import Q, Case, When, Value, IntegerField
|
|
|
|
|
from django.contrib.auth import login, logout
|
2025-08-23 19:00:21 +09:00
|
|
|
from A_core.sms_utils import send_verification_sms
|
|
|
|
|
from .log_utils import log_signup, log_phone_verification, log_search, log_main_access, log_error
|
2025-08-03 10:28:43 +09:00
|
|
|
import random
|
|
|
|
|
import json
|
2025-08-23 19:00:21 +09:00
|
|
|
import time
|
2025-08-03 10:28:43 +09:00
|
|
|
|
|
|
|
|
def password_required(request):
|
|
|
|
|
PASSWORD = '1110' # 실제 비밀번호
|
|
|
|
|
|
|
|
|
|
# 로그인이 된 사용자는 바로 메인 페이지로 리다이렉트
|
|
|
|
|
if request.user.is_authenticated:
|
|
|
|
|
next_url = request.GET.get("next", "/")
|
|
|
|
|
if not next_url:
|
|
|
|
|
next_url = "/"
|
|
|
|
|
return redirect(next_url)
|
|
|
|
|
|
|
|
|
|
if request.method == "POST":
|
|
|
|
|
entered_password = request.POST.get("password")
|
|
|
|
|
if entered_password == PASSWORD:
|
|
|
|
|
request.session["authenticated"] = True
|
|
|
|
|
next_url = request.POST.get("next", "/")
|
|
|
|
|
|
|
|
|
|
if not next_url:
|
|
|
|
|
next_url = "/"
|
|
|
|
|
|
|
|
|
|
return redirect(next_url)
|
|
|
|
|
else:
|
|
|
|
|
return render(request, "B_main/password.htm", {"error": "Incorrect password. Please try again."})
|
|
|
|
|
|
|
|
|
|
# GET 요청 시 비밀번호 입력 폼 렌더링
|
|
|
|
|
next_url = request.GET.get("next", "/")
|
|
|
|
|
return render(request, "B_main/password.htm", {"next": next_url})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 인증 검사 함수
|
|
|
|
|
def check_authentication(request):
|
|
|
|
|
# 로그인이 된 사용자는 인증 통과
|
|
|
|
|
if request.user.is_authenticated:
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
# 세션 인증이 된 사용자도 통과
|
|
|
|
|
if request.session.get("authenticated"):
|
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
# 둘 다 안 된 경우에만 비밀번호 페이지로 리다이렉트
|
|
|
|
|
return redirect(f"/accounts/login/?next={request.path}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main(request):
|
|
|
|
|
auth_check = check_authentication(request)
|
|
|
|
|
if auth_check:
|
|
|
|
|
return auth_check
|
2025-08-23 19:00:21 +09:00
|
|
|
|
|
|
|
|
# 메인 페이지 접속 로그 기록
|
|
|
|
|
log_main_access(request)
|
2025-08-03 10:28:43 +09:00
|
|
|
|
|
|
|
|
# 현재 사용자의 Person 정보 가져오기
|
|
|
|
|
current_user_person = None
|
|
|
|
|
if request.user.is_authenticated:
|
|
|
|
|
try:
|
|
|
|
|
current_user_person = Person.objects.get(user=request.user)
|
|
|
|
|
except Person.DoesNotExist:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# 기본 필터: 이름이 있는 사람들
|
|
|
|
|
base_filter = Person.objects.filter(
|
|
|
|
|
이름__isnull=False
|
|
|
|
|
).exclude(
|
|
|
|
|
이름__exact=''
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 현재 사용자의 권한에 따라 추가 필터 적용
|
2025-08-03 12:49:28 +09:00
|
|
|
if request.user.is_superuser or current_user_person is None:
|
|
|
|
|
# 모든 사람 표시 (필터 추가 없음)
|
2025-08-23 19:00:21 +09:00
|
|
|
pass
|
2025-08-03 12:49:28 +09:00
|
|
|
elif current_user_person and not current_user_person.모든사람보기권한:
|
|
|
|
|
# 모든사람보기권한이 False인 경우 회원가입한 사람만 표시
|
2025-08-03 10:28:43 +09:00
|
|
|
base_filter = base_filter.filter(user__isnull=False)
|
|
|
|
|
|
|
|
|
|
# 순서가 있는 항목을 먼저 보여주고, 나머지는 가나다순으로 정렬
|
|
|
|
|
people = base_filter.annotate(
|
|
|
|
|
sequence_order=Case(
|
|
|
|
|
When(SEQUENCE__isnull=True, then=Value(1)),
|
|
|
|
|
default=Value(0),
|
|
|
|
|
output_field=IntegerField(),
|
|
|
|
|
)
|
|
|
|
|
).order_by('sequence_order', 'SEQUENCE', '이름')
|
|
|
|
|
|
|
|
|
|
return render(request, 'B_main/main.htm', {'people': people})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def search_people(request):
|
|
|
|
|
auth_check = check_authentication(request)
|
|
|
|
|
if auth_check:
|
|
|
|
|
return auth_check
|
|
|
|
|
|
|
|
|
|
query = request.GET.get('q', '')
|
|
|
|
|
|
|
|
|
|
# 현재 사용자의 Person 정보 가져오기
|
|
|
|
|
current_user_person = None
|
|
|
|
|
if request.user.is_authenticated:
|
|
|
|
|
try:
|
|
|
|
|
current_user_person = Person.objects.get(user=request.user)
|
|
|
|
|
except Person.DoesNotExist:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
# 기본 필터: 모든 사람
|
|
|
|
|
base_filter = Person.objects.all()
|
|
|
|
|
|
|
|
|
|
# 현재 사용자의 권한에 따라 추가 필터 적용
|
2025-08-03 13:52:41 +09:00
|
|
|
if request.user.is_superuser or current_user_person is None:
|
|
|
|
|
# 모든 사람 표시 (필터 추가 없음)
|
2025-08-23 19:00:21 +09:00
|
|
|
pass
|
2025-08-03 13:52:41 +09:00
|
|
|
elif current_user_person and not current_user_person.모든사람보기권한:
|
|
|
|
|
# 모든사람보기권한이 False인 경우 회원가입한 사람만 표시
|
2025-08-03 10:28:43 +09:00
|
|
|
base_filter = base_filter.filter(user__isnull=False)
|
|
|
|
|
|
|
|
|
|
if query:
|
|
|
|
|
# 이름, 소속, 직책, 키워드로 검색
|
|
|
|
|
# 순서가 있는 항목을 먼저 보여주고, 나머지는 가나다순으로 정렬
|
|
|
|
|
people = base_filter.filter(
|
|
|
|
|
Q(이름__icontains=query) |
|
|
|
|
|
Q(소속__icontains=query) |
|
|
|
|
|
Q(TITLE__icontains=query) |
|
|
|
|
|
Q(직책__icontains=query) |
|
|
|
|
|
Q(keyword1__icontains=query) |
|
|
|
|
|
Q(생년월일__icontains=query)
|
|
|
|
|
).filter(
|
|
|
|
|
이름__isnull=False
|
|
|
|
|
).exclude(
|
|
|
|
|
이름__exact=''
|
|
|
|
|
).annotate(
|
|
|
|
|
sequence_order=Case(
|
|
|
|
|
When(SEQUENCE__isnull=True, then=Value(1)),
|
|
|
|
|
default=Value(0),
|
|
|
|
|
output_field=IntegerField(),
|
|
|
|
|
)
|
|
|
|
|
).order_by('sequence_order', 'SEQUENCE', '이름')
|
|
|
|
|
else:
|
|
|
|
|
# 순서가 있는 항목을 먼저 보여주고, 나머지는 가나다순으로 정렬
|
|
|
|
|
people = base_filter.filter(
|
|
|
|
|
이름__isnull=False
|
|
|
|
|
).exclude(
|
|
|
|
|
이름__exact=''
|
|
|
|
|
).annotate(
|
|
|
|
|
sequence_order=Case(
|
|
|
|
|
When(SEQUENCE__isnull=True, then=Value(1)),
|
|
|
|
|
default=Value(0),
|
|
|
|
|
output_field=IntegerField(),
|
|
|
|
|
)
|
|
|
|
|
).order_by('sequence_order', 'SEQUENCE', '이름')
|
2025-08-23 19:00:21 +09:00
|
|
|
|
|
|
|
|
# 검색 로그 기록
|
|
|
|
|
if query.strip():
|
|
|
|
|
log_search(request, query, people.count())
|
2025-08-03 10:28:43 +09:00
|
|
|
|
|
|
|
|
return render(request, 'B_main/partials/card_list.htm', {'people': people})
|
|
|
|
|
|
|
|
|
|
def vcard_download(request, name):
|
|
|
|
|
auth_check = check_authentication(request)
|
|
|
|
|
if auth_check:
|
|
|
|
|
return auth_check
|
|
|
|
|
|
|
|
|
|
name = unquote(name)
|
|
|
|
|
if not name:
|
|
|
|
|
return HttpResponse("Invalid name", status=400)
|
|
|
|
|
|
|
|
|
|
person = get_object_or_404(Person, 이름=name)
|
|
|
|
|
|
|
|
|
|
vcard_content = f"""BEGIN:VCARD
|
|
|
|
|
VERSION:3.0
|
|
|
|
|
N:{person.이름};;;;
|
|
|
|
|
FN:{person.이름}
|
|
|
|
|
ORG:{person.소속}
|
|
|
|
|
TITLE:{person.직책}
|
|
|
|
|
TEL;CELL:{person.연락처}
|
|
|
|
|
ADR:;;{person.주소}
|
|
|
|
|
END:VCARD
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
response = HttpResponse(vcard_content, content_type='text/vcard')
|
|
|
|
|
response['Content-Disposition'] = f'attachment; filename="{person.이름}.vcf"'
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def logout_view(request):
|
|
|
|
|
request.session.flush()
|
|
|
|
|
return redirect('/password/')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def my_profile(request):
|
|
|
|
|
try:
|
|
|
|
|
person = Person.objects.get(user=request.user)
|
|
|
|
|
except Person.DoesNotExist:
|
|
|
|
|
person = None
|
|
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
form = PersonForm(request.POST, instance=person)
|
|
|
|
|
if form.is_valid():
|
|
|
|
|
person = form.save(commit=False)
|
|
|
|
|
person.user = request.user
|
|
|
|
|
person.save()
|
|
|
|
|
return redirect('main') # or any success page
|
|
|
|
|
else:
|
|
|
|
|
form = PersonForm(instance=person)
|
|
|
|
|
|
|
|
|
|
return render(request, 'B_main/profile_form.htm', {'form': form})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
|
|
|
from django.views.decorators.http import require_http_methods
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
@csrf_exempt
|
|
|
|
|
@require_http_methods(["POST"])
|
|
|
|
|
def withdraw(request):
|
|
|
|
|
"""회원탈퇴 뷰"""
|
|
|
|
|
try:
|
|
|
|
|
# 현재 사용자의 Person 정보 가져오기
|
|
|
|
|
person = Person.objects.get(user=request.user)
|
|
|
|
|
|
|
|
|
|
# User 연결 해제
|
|
|
|
|
person.user = None
|
|
|
|
|
person.save()
|
|
|
|
|
|
2025-08-23 19:00:21 +09:00
|
|
|
# User 객체 삭제 (전화번호 계정 삭제)
|
2025-08-03 10:28:43 +09:00
|
|
|
user_phone = request.user.username
|
|
|
|
|
request.user.delete()
|
|
|
|
|
|
|
|
|
|
# 로그아웃
|
|
|
|
|
logout(request)
|
|
|
|
|
return JsonResponse({'success': True})
|
|
|
|
|
except Person.DoesNotExist:
|
|
|
|
|
return JsonResponse({'success': False, 'error': 'Person 정보를 찾을 수 없습니다.'})
|
|
|
|
|
except Exception as e:
|
|
|
|
|
return JsonResponse({'success': False, 'error': str(e)})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def session_logout(request):
|
|
|
|
|
try:
|
|
|
|
|
del request.session['authenticated']
|
|
|
|
|
except KeyError:
|
|
|
|
|
pass
|
|
|
|
|
return redirect('/')
|
|
|
|
|
|
|
|
|
|
def signup_view(request):
|
|
|
|
|
import random
|
|
|
|
|
from .forms import is_allowed_person
|
|
|
|
|
from django.contrib.auth import login
|
|
|
|
|
|
2025-08-24 18:31:27 +09:00
|
|
|
# 강제 리셋 파라미터 확인 (로그인 페이지에서 오는 경우)
|
|
|
|
|
force_reset = request.GET.get('reset', '').lower() == 'true'
|
|
|
|
|
|
2025-08-03 10:28:43 +09:00
|
|
|
# GET 요청 시 세션 초기화 (새로운 회원가입 시작)
|
|
|
|
|
# 단, 인증번호 확인 후 리다이렉트된 경우는 세션 유지
|
2025-08-24 18:31:27 +09:00
|
|
|
# 또한 step이 2이고 verified가 True인 경우도 세션 유지
|
|
|
|
|
current_step = request.session.get('signup_step', 1)
|
|
|
|
|
current_verified = request.session.get('signup_verified', False)
|
|
|
|
|
|
|
|
|
|
if request.method == 'GET' and (force_reset or not (current_verified and current_step == 2)):
|
|
|
|
|
# 강제 리셋이거나 인증되지 않았거나 step이 2가 아닌 경우에만 세션 초기화
|
|
|
|
|
if force_reset or not current_verified:
|
|
|
|
|
for key in ['signup_code', 'signup_name', 'signup_phone', 'signup_verified', 'signup_step']:
|
|
|
|
|
request.session.pop(key, None)
|
|
|
|
|
request.session['signup_step'] = 1
|
|
|
|
|
request.session['signup_verified'] = False
|
|
|
|
|
|
|
|
|
|
# 강제 리셋인 경우 디버그 메시지 출력
|
|
|
|
|
if force_reset:
|
|
|
|
|
print("[DEBUG] 회원가입 세션이 강제로 리셋되었습니다.")
|
2025-08-03 10:28:43 +09:00
|
|
|
|
|
|
|
|
step = request.session.get('signup_step', 1)
|
|
|
|
|
name = request.session.get('signup_name')
|
|
|
|
|
phone = request.session.get('signup_phone')
|
|
|
|
|
code_sent = bool(request.session.get('signup_code'))
|
|
|
|
|
verified = request.session.get('signup_verified', False)
|
|
|
|
|
|
|
|
|
|
# 1단계: 이름, 전화번호, 인증번호
|
|
|
|
|
if step == 1:
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
form = Step1PhoneForm(request.POST)
|
|
|
|
|
action = request.POST.get('action')
|
|
|
|
|
if action == 'send_code':
|
|
|
|
|
if form.is_valid():
|
|
|
|
|
name = form.cleaned_data['name']
|
|
|
|
|
phone = form.cleaned_data['phone']
|
|
|
|
|
|
|
|
|
|
# 폼 검증에서 이미 허가되지 않은 사용자 체크를 했으므로 여기서는 제거
|
|
|
|
|
code = str(random.randint(100000, 999999))
|
2025-08-23 19:00:21 +09:00
|
|
|
|
|
|
|
|
# 실제 SMS 발송
|
|
|
|
|
sms_result = send_verification_sms(phone, code)
|
|
|
|
|
|
|
|
|
|
if sms_result['success']:
|
|
|
|
|
request.session['signup_code'] = code
|
|
|
|
|
request.session['signup_name'] = name
|
|
|
|
|
request.session['signup_phone'] = phone
|
|
|
|
|
request.session['signup_verified'] = False
|
|
|
|
|
request.session['signup_code_sent_at'] = int(time.time())
|
|
|
|
|
|
|
|
|
|
# 전화번호 인증 로그 기록
|
|
|
|
|
log_phone_verification(request, phone)
|
|
|
|
|
|
2025-08-24 18:31:27 +09:00
|
|
|
# 텔레그램 알림 전송 (비동기)
|
|
|
|
|
from A_core.telegram_utils import send_signup_notification
|
|
|
|
|
send_signup_notification(name, phone, request)
|
|
|
|
|
|
2025-08-23 19:00:21 +09:00
|
|
|
return render(request, 'B_main/signup.html', {
|
|
|
|
|
'step': 1, 'form1': form, 'code_sent': True, 'message': '인증번호가 발송되었습니다.'
|
|
|
|
|
})
|
|
|
|
|
else:
|
|
|
|
|
pass
|
|
|
|
|
return render(request, 'B_main/signup.html', {
|
|
|
|
|
'step': 1, 'form1': form, 'code_sent': False,
|
|
|
|
|
'error': '인증번호 발송에 실패했습니다. 잠시 후 다시 시도해주세요.'
|
|
|
|
|
})
|
2025-08-03 10:28:43 +09:00
|
|
|
else:
|
|
|
|
|
# 폼 에러 메시지 확인
|
|
|
|
|
error_message = '입력 정보를 확인해주세요.'
|
|
|
|
|
if form.errors:
|
|
|
|
|
# 첫 번째 에러 메시지 사용
|
|
|
|
|
for field_errors in form.errors.values():
|
|
|
|
|
if field_errors:
|
|
|
|
|
error_message = field_errors[0]
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
return render(request, 'B_main/signup.html', {
|
|
|
|
|
'step': 1, 'form1': form, 'code_sent': False,
|
|
|
|
|
'error': error_message
|
|
|
|
|
})
|
|
|
|
|
elif action == 'verify_code':
|
|
|
|
|
if form.is_valid():
|
|
|
|
|
verification_code = form.cleaned_data['verification_code']
|
|
|
|
|
session_code = request.session.get('signup_code')
|
2025-08-23 19:00:21 +09:00
|
|
|
code_sent_at = request.session.get('signup_code_sent_at', 0)
|
|
|
|
|
current_time = int(time.time())
|
|
|
|
|
|
|
|
|
|
# 인증번호 만료 시간 체크 (3분)
|
|
|
|
|
if current_time - code_sent_at > 180:
|
|
|
|
|
return render(request, 'B_main/signup.html', {
|
|
|
|
|
'step': 1, 'form1': form, 'code_sent': False,
|
|
|
|
|
'error': '인증번호가 만료되었습니다. 다시 발송해주세요.'
|
|
|
|
|
})
|
|
|
|
|
|
2025-08-03 10:28:43 +09:00
|
|
|
if verification_code and verification_code == session_code:
|
|
|
|
|
# 인증 성공
|
|
|
|
|
request.session['signup_verified'] = True
|
|
|
|
|
request.session['signup_step'] = 2
|
2025-08-24 18:31:27 +09:00
|
|
|
# 인증 성공 메시지와 함께 2단계로 직접 이동
|
|
|
|
|
form2 = Step2AccountForm()
|
|
|
|
|
return render(request, 'B_main/signup.html', {
|
|
|
|
|
'step': 2,
|
|
|
|
|
'form2': form2,
|
|
|
|
|
'name': name,
|
|
|
|
|
'phone': phone,
|
|
|
|
|
'success_message': '인증이 완료되었습니다. 비밀번호를 설정해주세요.'
|
|
|
|
|
})
|
2025-08-03 10:28:43 +09:00
|
|
|
else:
|
|
|
|
|
return render(request, 'B_main/signup.html', {
|
|
|
|
|
'step': 1, 'form1': form, 'code_sent': True, 'error': '인증번호가 올바르지 않습니다.'
|
|
|
|
|
})
|
|
|
|
|
else:
|
|
|
|
|
return render(request, 'B_main/signup.html', {'step': 1, 'form1': form, 'code_sent': code_sent})
|
|
|
|
|
else:
|
|
|
|
|
form = Step1PhoneForm()
|
|
|
|
|
return render(request, 'B_main/signup.html', {'step': 1, 'form1': form, 'code_sent': False})
|
|
|
|
|
|
|
|
|
|
# 2단계: 이메일, 비밀번호, 비밀번호 확인
|
2025-08-23 19:00:21 +09:00
|
|
|
if step == 2:
|
|
|
|
|
# 세션이 만료되어 인증 정보가 없는 경우
|
|
|
|
|
if not verified or not name or not phone:
|
|
|
|
|
# 세션 초기화
|
|
|
|
|
for key in ['signup_code', 'signup_name', 'signup_phone', 'signup_verified', 'signup_step']:
|
|
|
|
|
request.session.pop(key, None)
|
|
|
|
|
request.session['signup_step'] = 1
|
|
|
|
|
request.session['signup_verified'] = False
|
|
|
|
|
|
|
|
|
|
form = Step1PhoneForm()
|
|
|
|
|
return render(request, 'B_main/signup.html', {
|
|
|
|
|
'step': 1,
|
|
|
|
|
'form1': form,
|
|
|
|
|
'code_sent': False,
|
|
|
|
|
'error': '세션이 만료되었습니다. 다시 인증해주세요.'
|
|
|
|
|
})
|
|
|
|
|
|
2025-08-03 10:28:43 +09:00
|
|
|
if request.method == 'POST':
|
|
|
|
|
form2 = Step2AccountForm(request.POST)
|
|
|
|
|
if form2.is_valid():
|
|
|
|
|
user = form2.save(name, phone, request)
|
2025-08-23 19:00:21 +09:00
|
|
|
|
|
|
|
|
# 회원가입 로그 기록
|
|
|
|
|
log_signup(request, user)
|
|
|
|
|
|
2025-08-03 10:28:43 +09:00
|
|
|
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
|
|
|
|
|
# 세션 정리
|
|
|
|
|
for key in ['signup_code', 'signup_name', 'signup_phone', 'signup_verified', 'signup_step']:
|
|
|
|
|
request.session.pop(key, None)
|
|
|
|
|
return redirect('main')
|
|
|
|
|
else:
|
|
|
|
|
return render(request, 'B_main/signup.html', {'step': 2, 'form2': form2, 'name': name, 'phone': phone})
|
|
|
|
|
else:
|
|
|
|
|
form2 = Step2AccountForm()
|
|
|
|
|
return render(request, 'B_main/signup.html', {'step': 2, 'form2': form2, 'name': name, 'phone': phone})
|
|
|
|
|
|
|
|
|
|
# 기본: 1단계로 초기화
|
|
|
|
|
request.session['signup_step'] = 1
|
|
|
|
|
request.session['signup_verified'] = False
|
2025-08-03 12:30:21 +09:00
|
|
|
return redirect('signup')
|
|
|
|
|
|
|
|
|
|
def privacy_policy(request):
|
|
|
|
|
"""개인정보처리방침 페이지"""
|
2025-08-23 19:00:21 +09:00
|
|
|
return render(request, 'privacy_policy.html')
|
|
|
|
|
|
|
|
|
|
def test_500_error(request):
|
|
|
|
|
"""500 에러 페이지 테스트용 뷰"""
|
|
|
|
|
# 강제로 에러를 발생시킵니다
|
2025-08-24 18:31:27 +09:00
|
|
|
raise Exception("500 에러 페이지 테스트를 위한 의도적인 에러입니다.")
|
|
|
|
|
|
|
|
|
|
def test_telegram_bot(request):
|
|
|
|
|
"""텔레그램 봇 테스트용 뷰 (관리자만 접근 가능)"""
|
|
|
|
|
if not request.user.is_superuser:
|
|
|
|
|
return redirect('/')
|
|
|
|
|
|
|
|
|
|
from A_core.telegram_utils import test_telegram_bot
|
|
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
success = test_telegram_bot()
|
|
|
|
|
if success:
|
|
|
|
|
messages.success(request, '✅ 텔레그램 봇 테스트 성공! 메시지가 전송되었습니다.')
|
|
|
|
|
else:
|
|
|
|
|
messages.error(request, '❌ 텔레그램 봇 테스트 실패! 설정을 확인해주세요.')
|
|
|
|
|
return redirect('test_telegram_bot')
|
|
|
|
|
|
|
|
|
|
return render(request, 'B_main/test_telegram.html')
|