diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py deleted file mode 100644 index fb051fd..0000000 --- a/accounts/migrations/0001_initial.py +++ /dev/null @@ -1,47 +0,0 @@ -# Generated by Django 6.0.7 on 2026-07-28 05:43 - -import django.contrib.auth.models -import django.contrib.auth.validators -import django.utils.timezone -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('auth', '0012_alter_user_first_name_max_length'), - ] - - operations = [ - migrations.CreateModel( - name='User', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), - ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('email', models.EmailField(max_length=254, unique=True, verbose_name='이메일')), - ('nickname', models.CharField(blank=True, max_length=50, verbose_name='닉네임')), - ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='생성일시')), - ('updated_at', models.DateTimeField(auto_now=True, verbose_name='수정일시')), - ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), - ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), - ], - options={ - 'verbose_name': '사용자', - 'verbose_name_plural': '사용자 목록', - 'db_table': 'users', - }, - managers=[ - ('objects', django.contrib.auth.models.UserManager()), - ], - ), - ] diff --git a/accounts/models.py b/accounts/models.py index f38c08f..7b03e9f 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -8,6 +8,8 @@ class User(AbstractUser): created_at = models.DateTimeField(auto_now_add=True, verbose_name="생성일시") updated_at = models.DateTimeField(auto_now=True, verbose_name="수정일시") + USERNAME_FIELD = 'email' + REQUIRED_FIELDS = ['username'] class Meta: db_table = 'users' diff --git a/config/settings.py b/config/settings.py index 37df1c6..09950f2 100644 --- a/config/settings.py +++ b/config/settings.py @@ -125,4 +125,5 @@ MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media' -AUTH_USER_MODEL = 'accounts.User' \ No newline at end of file +AUTH_USER_MODEL = 'accounts.User' +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' \ No newline at end of file diff --git a/exams/migrations/0001_initial.py b/exams/migrations/0001_initial.py deleted file mode 100644 index 6eeb1fb..0000000 --- a/exams/migrations/0001_initial.py +++ /dev/null @@ -1,112 +0,0 @@ -# Generated by Django 6.0.7 on 2026-07-28 05:43 - -import django.db.models.deletion -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='ExamPeriod', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=100, verbose_name='시험기간명')), - ('start_date', models.DateField(verbose_name='시작일')), - ('end_date', models.DateField(verbose_name='종료일')), - ('status', models.CharField(choices=[('draft', '작성 중'), ('active', '진행 중'), ('completed', '완료'), ('archived', '보관')], default='draft', max_length=20, verbose_name='시험기간 상태')), - ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='생성일시')), - ('updated_at', models.DateTimeField(auto_now=True, verbose_name='수정일시')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exam_periods', to=settings.AUTH_USER_MODEL, verbose_name='사용자')), - ], - options={ - 'verbose_name': '시험기간', - 'verbose_name_plural': '시험기간 목록', - 'db_table': 'exam_periods', - 'ordering': ['-start_date'], - }, - ), - migrations.CreateModel( - name='Exam', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=100, verbose_name='과목명')), - ('exam_date', models.DateField(verbose_name='시험일')), - ('importance', models.CharField(choices=[('high', '높음'), ('medium', '보통'), ('low', '낮음')], default='medium', max_length=10, verbose_name='우선순위')), - ('speed_factor', models.FloatField(default=1.0, verbose_name='공부 속도 보정계수')), - ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='생성일시')), - ('exam_period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exams', to='exams.examperiod', verbose_name='시험기간')), - ], - options={ - 'verbose_name': '시험 과목', - 'verbose_name_plural': '시험 과목 목록', - 'db_table': 'exams', - 'ordering': ['exam_date'], - }, - ), - migrations.CreateModel( - name='StudyMaterial', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.CharField(max_length=150, verbose_name='자료/범위명')), - ('file', models.FileField(blank=True, null=True, upload_to='materials/%Y/%m/', verbose_name='첨부 파일(PDF)')), - ('extracted_text', models.TextField(blank=True, null=True, verbose_name='추출된 텍스트 내용')), - ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='생성일시')), - ('exam', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='study_materials', to='exams.exam', verbose_name='시험 과목')), - ], - options={ - 'verbose_name': '학습 자료', - 'verbose_name_plural': '학습 자료 목록', - 'db_table': 'study_materials', - }, - ), - migrations.CreateModel( - name='StudyTask', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('unit_name', models.CharField(blank=True, max_length=100, null=True, verbose_name='단원명')), - ('title', models.CharField(max_length=200, verbose_name='학습 작업명')), - ('task_type', models.CharField(blank=True, max_length=50, null=True, verbose_name='작업 유형')), - ('importance', models.CharField(choices=[('high', '높음'), ('medium', '보통'), ('low', '낮음')], default='medium', max_length=10, verbose_name='중요도')), - ('depth', models.CharField(choices=[('core', '핵심'), ('basic', '기본'), ('optional', '선택')], default='basic', max_length=10, verbose_name='학습 깊이')), - ('difficulty', models.CharField(choices=[('easy', '쉬움'), ('normal', '보통'), ('hard', '어려움')], default='normal', max_length=10, verbose_name='난이도')), - ('estimated_min_minutes', models.PositiveIntegerField(default=0, verbose_name='최소 예상시간(분)')), - ('estimated_max_minutes', models.PositiveIntegerField(default=0, verbose_name='최대 예상시간(분)')), - ('ai_reason', models.TextField(blank=True, null=True, verbose_name='AI 추천 이유')), - ('is_confirmed', models.BooleanField(default=False, verbose_name='작업 확정 여부')), - ('order', models.PositiveIntegerField(default=1, verbose_name='작업 순서')), - ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='생성일시')), - ('exam', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='study_tasks', to='exams.exam', verbose_name='시험 과목')), - ('study_material', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='study_tasks', to='exams.studymaterial', verbose_name='관련 학습 자료')), - ], - options={ - 'verbose_name': '학습 작업', - 'verbose_name_plural': '학습 작업 목록', - 'db_table': 'study_tasks', - 'ordering': ['order', 'id'], - }, - ), - migrations.CreateModel( - name='AvailableTime', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('date', models.DateField(verbose_name='날짜')), - ('available_minutes', models.PositiveIntegerField(default=0, verbose_name='공부 가능시간(분)')), - ('exam_period', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='available_times', to='exams.examperiod', verbose_name='시험기간')), - ], - options={ - 'verbose_name': '날짜별 가용시간', - 'verbose_name_plural': '날짜별 가용시간 목록', - 'db_table': 'available_times', - 'ordering': ['date'], - 'unique_together': {('exam_period', 'date')}, - }, - ), - ] diff --git a/exams/migrations/0002_remove_exam_importance_exam_priority_and_more.py b/exams/migrations/0002_remove_exam_importance_exam_priority_and_more.py deleted file mode 100644 index 3c72329..0000000 --- a/exams/migrations/0002_remove_exam_importance_exam_priority_and_more.py +++ /dev/null @@ -1,72 +0,0 @@ -# Generated by Django 5.2.16 on 2026-07-28 13:46 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('exams', '0001_initial'), - ] - - operations = [ - migrations.RemoveField( - model_name='exam', - name='importance', - ), - migrations.AddField( - model_name='exam', - name='priority', - field=models.CharField(choices=[('high', '높음'), ('medium', '보통'), ('low', '낮음')], default='medium', max_length=10, verbose_name='과목 우선순위'), - ), - migrations.AddField( - model_name='studymaterial', - name='error_message', - field=models.TextField(blank=True, null=True, verbose_name='추출/파싱 실패 원인'), - ), - migrations.AddField( - model_name='studymaterial', - name='material_type', - field=models.CharField(choices=[('pdf', 'PDF 파일'), ('text', '텍스트 직접 입력')], default='text', max_length=10, verbose_name='자료 입력 유형'), - ), - migrations.AddField( - model_name='studymaterial', - name='status', - field=models.CharField(choices=[('pending', '대기 중'), ('processing', '처리 중'), ('completed', '완료'), ('failed', '실패')], default='pending', max_length=20, verbose_name='텍스트 추출 상태'), - ), - migrations.AddField( - model_name='studytask', - name='is_user_modified', - field=models.BooleanField(default=False, verbose_name='사용자 직접 수정 여부'), - ), - migrations.AlterField( - model_name='availabletime', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - migrations.AlterField( - model_name='exam', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - migrations.AlterField( - model_name='examperiod', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - migrations.AlterField( - model_name='studymaterial', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - migrations.AlterField( - model_name='studytask', - name='id', - field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), - ), - migrations.AlterField( - model_name='studytask', - name='task_type', - field=models.CharField(choices=[('concept', '개념 학습'), ('practice', '문제 풀이'), ('review', '복습'), ('summary', '요약 정리'), ('custom', '기타/직접 입력')], default='concept', max_length=20, verbose_name='작업 유형'), - ), - ]