Skip to content

Commit 4f23226

Browse files
authored
Merge pull request #178 from pirogramming/refactor/#177
Refactor: 필요 없는 컬럼 및 ProjectApplication 모델 제거
2 parents c1feea0 + 79d7d3a commit 4f23226

5 files changed

Lines changed: 52 additions & 114 deletions

File tree

apps/projects/admin.py

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,17 @@
33
from django.core.exceptions import ValidationError
44
from django.utils.translation import ngettext
55

6-
from .models import Season, Project, ProjectApplication
6+
from .models import Season, Project
77
from .services import TeamMatchingService, EmailService
88

99

1010
@admin.register(Season)
1111
class SeasonAdmin(admin.ModelAdmin):
12-
list_display = ["name", "status", "is_active", "matching_start", "matching_end", "project_start", "project_end"]
13-
list_filter = ["status", "is_active", "created_at"]
12+
list_display = ["name", "status", "matching_start", "matching_end", "project_start", "project_end"]
13+
list_filter = ["status", "created_at"]
1414
search_fields = ["name"]
1515
ordering = ["-created_at"]
16-
actions = ["activate_season", "deactivate_season", "run_team_matching", "send_matching_start_email", "send_matching_results_email"]
17-
18-
def activate_season(self, request, queryset):
19-
"""시즌 활성화 (이전 활성 시즌은 자동 비활성화)"""
20-
# 모든 시즌 비활성화
21-
Season.objects.all().update(is_active=False)
22-
# 선택된 시즌만 활성화
23-
queryset.update(is_active=True)
24-
self.message_user(request, "시즌이 활성화되었습니다.")
25-
26-
def deactivate_season(self, request, queryset):
27-
"""시즌 비활성화"""
28-
queryset.update(is_active=False)
29-
self.message_user(request, "시즌이 비활성화되었습니다.")
16+
actions = ["run_team_matching", "send_matching_start_email", "send_matching_results_email"]
3017

3118
def run_team_matching(self, request, queryset):
3219
"""팀 매칭 알고리즘 실행"""
@@ -92,9 +79,6 @@ def send_matching_start_email(self, request, queryset):
9279
run_team_matching.short_description = "🤝 팀 매칭 알고리즘 실행"
9380
send_matching_start_email.short_description = "📢 팀 매칭 시작 알림 이메일 발송"
9481
send_matching_results_email.short_description = "📧 팀 매칭 결과 이메일 발송"
95-
96-
activate_season.short_description = "✅ 선택된 시즌 활성화"
97-
deactivate_season.short_description = "❌ 선택된 시즌 비활성화"
9882

9983

10084
@admin.register(Project)
@@ -180,11 +164,3 @@ def change_status_to_archived(self, request, queryset):
180164
messages.SUCCESS,
181165
)
182166
change_status_to_archived.short_description = "📦 상태 변경: 보관됨"
183-
184-
185-
@admin.register(ProjectApplication)
186-
class ProjectApplicationAdmin(admin.ModelAdmin):
187-
list_display = ["id", "project", "user", "role", "passion_level", "status", "applied_at"]
188-
list_filter = ["status", "role", "passion_level"]
189-
search_fields = ["project__title", "user__nickname"]
190-
ordering = ["-applied_at"]
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Generated by Django 5.2.10 on 2026-02-13 04:07
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('projects', '0008_projectlike'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name='projectapplication',
15+
name='project',
16+
),
17+
migrations.RemoveField(
18+
model_name='projectapplication',
19+
name='role',
20+
),
21+
migrations.RemoveField(
22+
model_name='projectapplication',
23+
name='user',
24+
),
25+
migrations.RemoveIndex(
26+
model_name='season',
27+
name='seasons_is_acti_2e3a86_idx',
28+
),
29+
migrations.RemoveField(
30+
model_name='project',
31+
name='is_favorite',
32+
),
33+
migrations.RemoveField(
34+
model_name='project',
35+
name='target_team_size',
36+
),
37+
migrations.RemoveField(
38+
model_name='season',
39+
name='is_active',
40+
),
41+
migrations.DeleteModel(
42+
name='ProjectApplication',
43+
),
44+
]

apps/projects/models.py

Lines changed: 4 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,13 @@ class Status(models.TextChoices):
3636
project_start = models.DateTimeField(help_text="프로젝트 시작")
3737
project_end = models.DateTimeField(help_text="프로젝트 종료")
3838

39-
is_active = models.BooleanField(
40-
default=False,
41-
help_text="현재 진행 중인 시즌",
42-
)
43-
4439
created_at = models.DateTimeField(auto_now_add=True)
4540
updated_at = models.DateTimeField(auto_now=True)
4641

4742
class Meta:
4843
db_table = "seasons"
4944
ordering = ["-created_at"]
5045
indexes = [
51-
models.Index(fields=["is_active"]),
5246
models.Index(fields=["status"]),
5347
]
5448

@@ -67,8 +61,10 @@ def is_project_period(self) -> bool:
6761

6862
@classmethod
6963
def get_active_season(cls):
70-
"""현재 활성화된 시즌 반환"""
71-
return cls.objects.filter(is_active=True).first()
64+
"""현재 활성화된 시즌 반환 (진행 중인 시즌)"""
65+
return cls.objects.filter(
66+
status__in=[cls.Status.MATCHING, cls.Status.IN_PROJECT]
67+
).order_by('-created_at').first()
7268

7369

7470
class Project(models.Model):
@@ -121,11 +117,6 @@ class Status(models.TextChoices):
121117
help_text="프로젝트 기간 (주)",
122118
)
123119

124-
target_team_size = models.SmallIntegerField(
125-
default=5,
126-
help_text="목표 팀 인원 (PM1/FE2/BE2 = 5명)",
127-
)
128-
129120
status = models.CharField(
130121
max_length=20,
131122
choices=Status.choices,
@@ -172,11 +163,6 @@ class Status(models.TextChoices):
172163
help_text="관련 링크 (마크다운)",
173164
)
174165

175-
is_favorite = models.BooleanField(
176-
default=False,
177-
help_text="즐겨찾기 여부",
178-
)
179-
180166
created_at = models.DateTimeField(auto_now_add=True)
181167
updated_at = models.DateTimeField(auto_now=True)
182168

@@ -208,74 +194,6 @@ def toggle_like(self, user):
208194
return created # True: 좋아요 추가, False: 좋아요 제거
209195

210196

211-
class ProjectApplication(models.Model):
212-
"""
213-
프로젝트 지원
214-
- 열정 레벨 (1~4) 저장
215-
- 지원 역할 선택
216-
"""
217-
218-
class Status(models.TextChoices):
219-
APPLIED = "APPLIED", "지원됨"
220-
CANCELLED = "CANCELLED", "취소됨"
221-
MATCHED = "MATCHED", "매칭됨"
222-
REJECTED = "REJECTED", "거절됨"
223-
224-
project = models.ForeignKey(
225-
Project,
226-
on_delete=models.CASCADE,
227-
related_name="applications",
228-
)
229-
230-
user = models.ForeignKey(
231-
settings.AUTH_USER_MODEL,
232-
on_delete=models.CASCADE,
233-
related_name="applications",
234-
)
235-
236-
role = models.ForeignKey(
237-
"accounts.Role",
238-
on_delete=models.PROTECT,
239-
related_name="applications",
240-
help_text="지원 역할 (PM/FRONTEND/BACKEND)",
241-
)
242-
243-
passion_level = models.SmallIntegerField(
244-
validators=[MinValueValidator(1), MaxValueValidator(4)],
245-
help_text="열정 레벨 (1~4, 설문 결과)",
246-
)
247-
248-
status = models.CharField(
249-
max_length=20,
250-
choices=Status.choices,
251-
default=Status.APPLIED,
252-
)
253-
254-
applied_at = models.DateTimeField(auto_now_add=True)
255-
updated_at = models.DateTimeField(auto_now=True)
256-
257-
class Meta:
258-
db_table = "project_applications"
259-
constraints = [
260-
models.UniqueConstraint(
261-
fields=["project", "user"],
262-
name="uq_project_application",
263-
),
264-
models.CheckConstraint(
265-
check=models.Q(passion_level__gte=1, passion_level__lte=4),
266-
name="ck_passion_level_range",
267-
),
268-
]
269-
indexes = [
270-
models.Index(fields=["project", "role", "status"]),
271-
models.Index(fields=["user", "status"]),
272-
models.Index(fields=["passion_level"]),
273-
]
274-
275-
def __str__(self) -> str:
276-
return f"{self.user}{self.project} ({self.role.code})"
277-
278-
279197
class ProjectLike(models.Model):
280198
"""
281199
프로젝트 좋아요

templates/projects/project_detail.html

Whitespace-only changes.

templates/projects/project_list.html

Whitespace-only changes.

0 commit comments

Comments
 (0)