SillaAMP_V2/B_main/views.py

373 lines
14 KiB
Python
Raw Normal View History

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
import random
import json
def password_required(request):
PASSWORD = '1110' # 실제 비밀번호
# 디버깅을 위한 로그
print(f"[DEBUG] password_required - user.is_authenticated: {request.user.is_authenticated}")
print(f"[DEBUG] password_required - user: {request.user}")
# 로그인이 된 사용자는 바로 메인 페이지로 리다이렉트
if request.user.is_authenticated:
next_url = request.GET.get("next", "/")
if not next_url:
next_url = "/"
print(f"[DEBUG] User is authenticated, redirecting to: {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):
# 디버깅을 위한 로그
print(f"[DEBUG] check_authentication - user.is_authenticated: {request.user.is_authenticated}")
print(f"[DEBUG] check_authentication - session.authenticated: {request.session.get('authenticated')}")
print(f"[DEBUG] check_authentication - user: {request.user}")
# 로그인이 된 사용자는 인증 통과
if request.user.is_authenticated:
print(f"[DEBUG] User is authenticated, allowing access")
return None
# 세션 인증이 된 사용자도 통과
if request.session.get("authenticated"):
print(f"[DEBUG] Session is authenticated, allowing access")
return None
# 둘 다 안 된 경우에만 비밀번호 페이지로 리다이렉트
print(f"[DEBUG] No authentication found, redirecting to password page")
return redirect(f"/accounts/login/?next={request.path}")
def main(request):
auth_check = check_authentication(request)
if auth_check:
return auth_check
# 현재 사용자의 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=''
)
# 현재 사용자의 권한에 따라 추가 필터 적용
if current_user_person and not current_user_person.모든사람보기권한:
# 모든사람보기권한이 False인 경우 회원가입한 사람만 표시 (user가 있는 사람들)
base_filter = base_filter.filter(user__isnull=False)
print(f"[DEBUG] 회원가입자만 표시 모드: {current_user_person.이름}")
else:
print(f"[DEBUG] 모든 사람 표시 모드")
# 순서가 있는 항목을 먼저 보여주고, 나머지는 가나다순으로 정렬
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', '이름')
print(f"[DEBUG] 메인 페이지 표시: {people.count()}")
for person in people:
status = "회원가입" if person.user else "미가입"
print(f"[DEBUG] - {person.이름} (상태: {status})")
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', '')
print(f"[DEBUG] 검색 쿼리: '{query}'")
# 현재 사용자의 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()
# 현재 사용자의 권한에 따라 추가 필터 적용
if current_user_person and not current_user_person.모든사람보기권한:
# 모든사람보기권한이 False인 경우 회원가입한 사람만 표시 (user가 있는 사람들)
base_filter = base_filter.filter(user__isnull=False)
print(f"[DEBUG] 검색 - 회원가입자만 표시 모드: {current_user_person.이름}")
else:
print(f"[DEBUG] 검색 - 모든 사람 표시 모드")
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', '이름')
print(f"[DEBUG] 검색 결과: {people.count()}")
for person in people:
print(f"[DEBUG] - {person.이름} (소속: {person.소속}, 직책: {person.직책})")
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', '이름')
print(f"[DEBUG] 전체 목록: {people.count()}")
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()
# User 객체 삭제 (전화번호 계정 삭제)
user_phone = request.user.username
request.user.delete()
# 로그아웃
logout(request)
print(f"[DEBUG] 회원탈퇴 완료: {user_phone} (User 삭제, Person 연결 해제)")
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
# GET 요청 시 세션 초기화 (새로운 회원가입 시작)
# 단, 인증번호 확인 후 리다이렉트된 경우는 세션 유지
if request.method == 'GET' and not request.session.get('signup_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
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))
request.session['signup_code'] = code
request.session['signup_name'] = name
request.session['signup_phone'] = phone
request.session['signup_verified'] = False
print(f"[DEBUG] 인증번호 발송: {name} ({phone}) - {code}")
return render(request, 'B_main/signup.html', {
'step': 1, 'form1': form, 'code_sent': True, 'message': '인증번호가 발송되었습니다.'
})
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')
if verification_code and verification_code == session_code:
# 인증 성공
request.session['signup_verified'] = True
request.session['signup_step'] = 2
return redirect('signup')
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단계: 이메일, 비밀번호, 비밀번호 확인
if step == 2 and verified and name and phone:
if request.method == 'POST':
form2 = Step2AccountForm(request.POST)
if form2.is_valid():
user = form2.save(name, phone, request)
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
return redirect('signup')