from django import forms from django.contrib.auth import get_user_model from B_main.models import Person # 또는 Person 모델이 정의된 경로로 import import random import re User = get_user_model() def format_phone_number(phone): """전화번호에서 대시 제거""" return re.sub(r'[^0-9]', '', phone) class CustomFileInput(forms.FileInput): def get_context(self, name, value, attrs): context = super().get_context(name, value, attrs) # "Currently:" 텍스트 제거 if 'help_text' in context: context['help_text'] = '' return context class ProfileFullEditForm(forms.ModelForm): # 통합된 이름 필드 (편집 불가능) full_name = forms.CharField( label="이름", required=False, widget=forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-600 bg-opacity-80 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'readonly': 'readonly', 'placeholder': '이름' }) ) class Meta: model = Person fields = [ '소속', '직책', '주소', '사진', 'keyword1' ] widgets = { '소속': forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '소속' }), '직책': forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '직책' }), '주소': forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '주소' }), '사진': CustomFileInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'accept': 'image/*' }), 'keyword1': forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '검색 키워드 (예: 회계감사)' }), } def __init__(self, *args, **kwargs): self.user = kwargs.pop('user') super().__init__(*args, **kwargs) # 통합된 이름 설정 (first_name + last_name) full_name = f"{self.user.first_name or ''} {self.user.last_name or ''}".strip() self.fields['full_name'].initial = full_name # Person 모델 필드 초기값 설정 (기존 인스턴스가 있는 경우) if self.instance and self.instance.pk: # 기존 Person 인스턴스의 데이터로 초기화 for field_name in self.fields: if field_name == 'full_name': continue if hasattr(self.instance, field_name): self.fields[field_name].initial = getattr(self.instance, field_name) def save(self, commit=True): # Person 모델 저장 (User 모델은 수정하지 않음) if commit: instance = super().save(commit=False) instance.user = self.user instance.save() return self.user # 모드1: 비밀번호 찾기 폼 class PasswordResetStep1Form(forms.Form): """비밀번호 찾기 1단계: 전화번호 인증""" phone = forms.CharField( max_length=11, label='전화번호', widget=forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '01012345678' }) ) verification_code = forms.CharField( max_length=6, label='인증번호', required=False, widget=forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '6자리 인증번호' }) ) def clean_phone(self): phone = self.cleaned_data.get('phone') if phone: # 전화번호 포맷팅 적용 (대시 제거) formatted_phone = format_phone_number(phone) # 해당 전화번호로 가입된 사용자가 있는지 확인 try: user = User.objects.get(username=formatted_phone) return formatted_phone except User.DoesNotExist: raise forms.ValidationError('등록되지 않은 전화번호입니다.') return phone # 모드2: 로그인 상태 비밀번호 변경 폼 class PasswordChangeLoggedInForm(forms.Form): """로그인 상태에서 비밀번호 변경""" current_password = forms.CharField( label='현재 비밀번호', widget=forms.PasswordInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '현재 비밀번호' }) ) new_password1 = forms.CharField( label='새 비밀번호', widget=forms.PasswordInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '새 비밀번호' }) ) new_password2 = forms.CharField( label='새 비밀번호 확인', widget=forms.PasswordInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '새 비밀번호 확인' }) ) def __init__(self, *args, **kwargs): self.user = kwargs.pop('user', None) super().__init__(*args, **kwargs) def clean_current_password(self): current_password = self.cleaned_data.get('current_password') if self.user and not self.user.check_password(current_password): raise forms.ValidationError('현재 비밀번호가 올바르지 않습니다.') return current_password def clean(self): cleaned_data = super().clean() password1 = cleaned_data.get('new_password1') password2 = cleaned_data.get('new_password2') if password1 and password2 and password1 != password2: raise forms.ValidationError('새 비밀번호가 일치하지 않습니다.') if password1 and len(password1) < 8: raise forms.ValidationError('비밀번호는 최소 8자 이상이어야 합니다.') return cleaned_data # 모드3: 강제 비밀번호 설정 폼 class ForcePasswordSetForm(forms.Form): """강제 비밀번호 설정""" new_password1 = forms.CharField( label='새 비밀번호', widget=forms.PasswordInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '새 비밀번호' }) ) new_password2 = forms.CharField( label='새 비밀번호 확인', widget=forms.PasswordInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '새 비밀번호 확인' }) ) def clean(self): cleaned_data = super().clean() password1 = cleaned_data.get('new_password1') password2 = cleaned_data.get('new_password2') if password1 and password2 and password1 != password2: raise forms.ValidationError('비밀번호가 일치하지 않습니다.') if password1 and len(password1) < 8: raise forms.ValidationError('비밀번호는 최소 8자 이상이어야 합니다.') return cleaned_data # 기존 폼들 (유지) class PasswordChangeStep1Form(forms.Form): """비밀번호 변경 1단계: 전화번호 인증""" phone = forms.CharField( max_length=11, label='전화번호', widget=forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '01012345678' }) ) verification_code = forms.CharField( max_length=6, label='인증번호', required=False, widget=forms.TextInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '6자리 인증번호' }) ) def clean(self): cleaned_data = super().clean() phone = cleaned_data.get('phone') if phone: # 전화번호 포맷팅 적용 (대시 제거) formatted_phone = format_phone_number(phone) cleaned_data['phone'] = formatted_phone # 현재 로그인한 사용자의 전화번호와 일치하는지 확인 if not self.user or self.user.username != formatted_phone: raise forms.ValidationError('등록된 전화번호와 일치하지 않습니다.') return cleaned_data def __init__(self, *args, **kwargs): self.user = kwargs.pop('user', None) super().__init__(*args, **kwargs) class PasswordChangeStep2Form(forms.Form): """비밀번호 변경 2단계: 새 비밀번호 입력""" new_password1 = forms.CharField( label='새 비밀번호', widget=forms.PasswordInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '새 비밀번호' }) ) new_password2 = forms.CharField( label='새 비밀번호 확인', widget=forms.PasswordInput(attrs={ 'class': 'w-full px-4 py-3 rounded-xl bg-gray-700 bg-opacity-80 text-white placeholder-gray-400 border border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 transition', 'placeholder': '새 비밀번호 확인' }) ) def clean(self): cleaned_data = super().clean() password1 = cleaned_data.get('new_password1') password2 = cleaned_data.get('new_password2') if password1 and password2 and password1 != password2: raise forms.ValidationError('비밀번호가 일치하지 않습니다.') if password1 and len(password1) < 8: raise forms.ValidationError('비밀번호는 최소 8자 이상이어야 합니다.') return cleaned_data