117 lines
5.9 KiB
Python
117 lines
5.9 KiB
Python
import os
|
|
from django.utils.deconstruct import deconstructible
|
|
from django.db import models
|
|
from django.contrib.auth.models import User
|
|
|
|
@deconstructible
|
|
class StaticImagePath(object):
|
|
def __call__(self, instance, filename):
|
|
# B_main 앱 폴더 하위의 static/B_main/images/에 저장
|
|
return f'B_main/static/B_main/images/{filename}'
|
|
|
|
class Person(models.Model):
|
|
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
|
|
이름 = models.CharField(max_length=50)
|
|
소속 = models.CharField(max_length=100)
|
|
생년월일 = models.DateField(null=True, blank=True)
|
|
직책 = models.CharField(max_length=50)
|
|
연락처 = models.CharField(max_length=20)
|
|
주소 = models.CharField(max_length=255)
|
|
사진 = models.ImageField(upload_to='profile_photos/', default='profile_photos/default_user.png', blank=True)
|
|
TITLE = models.CharField(max_length=50, blank=True, null=True)
|
|
SEQUENCE = models.IntegerField(blank=True, null=True)
|
|
모든사람보기권한 = models.BooleanField(default=False, verbose_name='모든 사람 보기 권한', help_text='True인 경우 모든 사람을 볼 수 있고, False인 경우 회원가입한 사람만 볼 수 있습니다.')
|
|
keyword1 = models.CharField(max_length=50, blank=True, null=True, verbose_name='검색 키워드', help_text='다른 사람들이 당신을 찾을 수 있도록 키워드를 입력하세요 (예: 회계감사)')
|
|
소개글 = models.TextField(max_length=200, blank=True, null=True, verbose_name='소개글', help_text='자신을 소개하는 간단한 글을 작성하세요 (최대 200자)')
|
|
비밀번호설정필요 = models.BooleanField(default=False, verbose_name='비밀번호 설정 필요', help_text='True인 경우 사용자가 메인페이지 접근 시 비밀번호 설정 페이지로 리다이렉트됩니다.')
|
|
가입일시 = models.DateTimeField(null=True, blank=True, verbose_name='가입일시', help_text='회원가입을 완료한 날짜와 시간')
|
|
|
|
class Meta:
|
|
verbose_name = '사람'
|
|
verbose_name_plural = '사람들'
|
|
|
|
def __str__(self):
|
|
return self.이름
|
|
|
|
|
|
class AccessLog(models.Model):
|
|
"""사용자 접속 및 활동 로그"""
|
|
|
|
ACTION_CHOICES = [
|
|
('LOGIN', '로그인'),
|
|
('LOGOUT', '로그아웃'),
|
|
('SIGNUP', '회원가입'),
|
|
('PROFILE_UPDATE', '회원정보수정'),
|
|
('PASSWORD_CHANGE', '비밀번호변경'),
|
|
('PHONE_VERIFICATION', '전화번호인증'),
|
|
('SEARCH', '검색'),
|
|
('VIEW_PROFILE', '프로필조회'),
|
|
('MAIN_ACCESS', '메인페이지접속'),
|
|
('ERROR', '에러발생'),
|
|
('OTHER', '기타'),
|
|
]
|
|
|
|
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='사용자')
|
|
person = models.ForeignKey(Person, on_delete=models.SET_NULL, null=True, blank=True, verbose_name='Person')
|
|
action = models.CharField(max_length=20, choices=ACTION_CHOICES, verbose_name='활동유형')
|
|
description = models.TextField(blank=True, null=True, verbose_name='상세설명')
|
|
ip_address = models.GenericIPAddressField(null=True, blank=True, verbose_name='IP주소')
|
|
user_agent = models.TextField(blank=True, null=True, verbose_name='사용자에이전트')
|
|
session_key = models.CharField(max_length=40, blank=True, null=True, verbose_name='세션키')
|
|
timestamp = models.DateTimeField(auto_now_add=True, verbose_name='발생시간')
|
|
|
|
# 추가 메타데이터 (JSON 형태로 저장)
|
|
metadata = models.JSONField(default=dict, blank=True, verbose_name='추가정보')
|
|
|
|
class Meta:
|
|
verbose_name = '접속 로그'
|
|
verbose_name_plural = '접속 로그들'
|
|
ordering = ['-timestamp']
|
|
indexes = [
|
|
models.Index(fields=['user', '-timestamp']),
|
|
models.Index(fields=['action', '-timestamp']),
|
|
models.Index(fields=['-timestamp']),
|
|
models.Index(fields=['ip_address', '-timestamp']),
|
|
]
|
|
|
|
def __str__(self):
|
|
user_name = self.person.이름 if self.person else (self.user.username if self.user else '익명')
|
|
return f"{user_name} - {self.get_action_display()} ({self.timestamp.strftime('%Y-%m-%d %H:%M:%S')})"
|
|
|
|
|
|
class WithdrawalRequest(models.Model):
|
|
"""회원탈퇴 요청"""
|
|
|
|
STATUS_CHOICES = [
|
|
('PENDING', '승인 대기'),
|
|
('APPROVED', '승인 완료'),
|
|
('REJECTED', '승인 거부'),
|
|
]
|
|
|
|
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name='탈퇴 요청자')
|
|
person = models.ForeignKey(Person, on_delete=models.CASCADE, verbose_name='Person 정보')
|
|
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='PENDING', verbose_name='승인 상태')
|
|
reason = models.TextField(blank=True, null=True, verbose_name='탈퇴 사유')
|
|
request_date = models.DateTimeField(auto_now_add=True, verbose_name='요청 일시')
|
|
|
|
# 승인 관련 정보
|
|
approved_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True,
|
|
related_name='approved_withdrawals', verbose_name='승인자')
|
|
approved_date = models.DateTimeField(null=True, blank=True, verbose_name='승인 일시')
|
|
admin_notes = models.TextField(blank=True, null=True, verbose_name='관리자 메모')
|
|
|
|
# 탈퇴 전 사용자 정보 백업 (이메일 발송용)
|
|
backup_data = models.JSONField(default=dict, verbose_name='탈퇴 전 정보 백업')
|
|
|
|
class Meta:
|
|
verbose_name = '회원탈퇴 요청'
|
|
verbose_name_plural = '회원탈퇴 요청들'
|
|
ordering = ['-request_date']
|
|
indexes = [
|
|
models.Index(fields=['status', '-request_date']),
|
|
models.Index(fields=['user', '-request_date']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"{self.person.이름} - {self.get_status_display()} ({self.request_date.strftime('%Y-%m-%d %H:%M')})"
|