From 0cfc5d657da04a7100f1faf78c70bc08036792d5 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 01:24:48 +0900 Subject: [PATCH 01/10] =?UTF-8?q?=E2=9E=95=20Dependency:=20ulid=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | Bin 592 -> 632 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index a4c944c47efd03ca87de4c5f96506fc7953fb7d5..b0d1326a99a46aa1e272c3c3fcb99b6c046e3da2 100644 GIT binary patch delta 43 xcmcb>@`Gi=J4X2ehDwGKh75*$hCBvchEj$chD?SO23sIBX3%3WnEaG68vqZP3i|*6 delta 11 Scmeyta)D*TJI2XkOi2JAs04ig From 75819f68b4ce4dbe854d97ae5cc7a5b3063a0fb5 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:42:04 +0900 Subject: [PATCH 02/10] =?UTF-8?q?=E2=9E=95=20Dependency:=20django-extensio?= =?UTF-8?q?ns=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=84=A4=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | Bin 632 -> 684 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/requirements.txt b/requirements.txt index b0d1326a99a46aa1e272c3c3fcb99b6c046e3da2..513391e7c5aa1d03c23286c55b5b2c9a7844e8aa 100644 GIT binary patch delta 52 zcmeytvW9ho2&1wtLn=cBLkW<~V<=|GWXK28whXom#teE4MnG&l*_KgzvmT=tBLF)d B3aS7A delta 12 TcmZ3(`h#VI2;*iC#uP>X9i#)) From 802f5a6fbc13116cc48f05d6effa06ce5c216770 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:50:49 +0900 Subject: [PATCH 03/10] =?UTF-8?q?=E2=9C=A8=20Feat:=20[#10]=20ulid,=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9D=BC,=20=EC=88=98=EC=A0=95=EC=9D=BC=20mo?= =?UTF-8?q?del=20=EC=B6=94=EC=83=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/models/baseModels.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 common/models/baseModels.py diff --git a/common/models/baseModels.py b/common/models/baseModels.py new file mode 100644 index 0000000..e89718e --- /dev/null +++ b/common/models/baseModels.py @@ -0,0 +1,17 @@ +from django.db import models + +from common.utils.codeManger import generate_ulid + + +class BaseModel(models.Model): + id = models.CharField( + max_length=26, + primary_key=True, + default=generate_ulid, + editable=False + ) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta: + abstract = True \ No newline at end of file From ed207f62dc9907c7d5483ec9b54b4f5a5a4216a0 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:52:15 +0900 Subject: [PATCH 04/10] =?UTF-8?q?=E2=9C=A8=20Feat:=20[#10]=20choice=20?= =?UTF-8?q?=EC=9A=94=EC=86=8C=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/models/choiceModels.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 common/models/choiceModels.py diff --git a/common/models/choiceModels.py b/common/models/choiceModels.py new file mode 100644 index 0000000..f2ea76e --- /dev/null +++ b/common/models/choiceModels.py @@ -0,0 +1,13 @@ +from django.db import models + +class GenderChoices(models.TextChoices): + MAN = '남', '남성' + WOMAN = '여', '여성' + +class CertificateCodeUseType(models.TextChoices): + EMAIL = '이메일', '이메일' + PHONE = '휴대폰', '휴대폰' + +class InviteCodeUseType(models.TextChoices): + PROJECT = '프로젝트', '프로젝트' + HACKATHON = '해커톤', '해커톤' From b8a8ff177b14c9cc594ecfc6309d1ca1a87a4d61 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:53:28 +0900 Subject: [PATCH 05/10] =?UTF-8?q?=E2=9C=A8=20Feat:=20[#10]=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=9C=A0=ED=9A=A8?= =?UTF-8?q?=EA=B8=B0=EA=B0=84=20=EC=84=A4=EC=A0=95=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/utils/codeManger.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 common/utils/codeManger.py diff --git a/common/utils/codeManger.py b/common/utils/codeManger.py new file mode 100644 index 0000000..8b1398f --- /dev/null +++ b/common/utils/codeManger.py @@ -0,0 +1,20 @@ +from random import randint, choices +from django.utils.timezone import now +from datetime import timedelta + +import ulid, uuid + +def generate_ulid(): + return str(ulid.ULID()) + +def generate_uuid(): + return str(uuid.uuid4()) + +allowed_char = ''.join(chr(i) for i in range(33, 127) if chr(i).isalnum()) + +def generate_code(code_len): # 코드 생성 + code = ''.join(choices(allowed_char, k=code_len)) + return code + +def set_expire(minutes): # 유효기간 설정 + return now() + timedelta(minutes=minutes) \ No newline at end of file From 8c655def8859891a39647a491f3a61a66c9f4391 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:55:26 +0900 Subject: [PATCH 06/10] =?UTF-8?q?=E2=9C=A8=20Feat:=20[#10]=20user=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- users/models.py | 59 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/users/models.py b/users/models.py index 79eba13..4ac7949 100644 --- a/users/models.py +++ b/users/models.py @@ -1,6 +1,59 @@ from django.db import models +from common.models.baseModels import BaseModel +from common.models.choiceModels import GenderChoices, CertificateCodeUseType +from common.utils.codeManger import set_expire -from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin, AbstractUser +from django.contrib.postgres.fields import ArrayField +from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin -class User(AbstractUser): - pass \ No newline at end of file +class UserManager(BaseUserManager): + def create_user(self, email, password, **kwargs): + user = self.model(email = email, **kwargs) + user.set_password(password) + user.save(using=self._db) + return user + + def create_superuser(self, email=None, password=None, **extra_fields): + superuser = self.create_user( + email = email, + password = password, + ) + + superuser.is_staff = True + superuser.is_superuser = True + superuser.is_active = True + + superuser.save(using=self._db) + return superuser + +class User(BaseModel, AbstractBaseUser, PermissionsMixin): + email = models.EmailField(unique=True) + is_email_verified = models.BooleanField(default=False) + is_plers_terms_of_service = models.BooleanField(default=False) + is_terms_of_service_colio = models.BooleanField(default=False) + is_consent_personal_info = models.BooleanField(default=False) + is_consent_third_party_sharing = models.BooleanField(default=False) + is_consent_marketing = models.BooleanField(default=False) + phone = models.CharField(max_length=11) + is_phone_verified = models.BooleanField(default=False) + nickname = models.CharField(default=False) + gender = models.CharField(choices=GenderChoices.choices, max_length=1) + birth_date = models.CharField(max_length=10) + custom_url = models.CharField(max_length=20) + job_and_interests = ArrayField(models.CharField(max_length=20), default=list) + skills = ArrayField(models.CharField(max_length=20), default=list, blank=True) + external_links = ArrayField(models.TextField(), default=list, blank=True) + short_bio = models.CharField(max_length=100, blank=True) + profile_image = models.ImageField(upload_to='', blank=True) + + is_staff = models.BooleanField(default=False) + is_active = models.BooleanField(default=True) + + objects = UserManager() + + USERNAME_FIELD = 'email' + REQUIRED_FIELDS = [] + + def __str__(self): + return self.nickname + \ No newline at end of file From c8d4dd651322d52492455551126e8cc5563f19d0 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:56:59 +0900 Subject: [PATCH 07/10] =?UTF-8?q?=E2=9C=A8=20Feat:=20[#10]=20project=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8,=20project/user=20=EC=A4=91=EA=B0=84=20?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- projects/models.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/projects/models.py b/projects/models.py index 71a8362..bcd3b10 100644 --- a/projects/models.py +++ b/projects/models.py @@ -1,3 +1,23 @@ from django.db import models -# Create your models here. +from common.models.baseModels import BaseModel + +from django.contrib.postgres.fields import ArrayField +from django.conf import settings + +from users.models import User + +class Project(BaseModel): + name = models.CharField(max_length=20) + is_team = models.BooleanField(default=False) + category = ArrayField(models.CharField(max_length=20), default=list) + is_published = models.BooleanField(default=False) + view_count = models.IntegerField(default=0) + like_count = models.IntegerField(default=0) + scrab_count = models.IntegerField(default=0) + is_represent = models.BooleanField(default=False) + code_id = models.CharField(max_length=26, blank=True) + +class ProjectTeamList(BaseModel): + project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='project_team_list', to_field='id') + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='project_team_list',to_field='id') From 64a8763c725fb6d9a7cab93cfae6ede21b0f7b78 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:57:49 +0900 Subject: [PATCH 08/10] =?UTF-8?q?=E2=9C=A8=20Feat:=20[#10]=20portfolio=20?= =?UTF-8?q?=EB=AA=A8=EB=8D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- portfolios/models.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/portfolios/models.py b/portfolios/models.py index 71a8362..6a68602 100644 --- a/portfolios/models.py +++ b/portfolios/models.py @@ -1,3 +1,20 @@ from django.db import models -# Create your models here. +from common.models.baseModels import BaseModel + +from django.contrib.postgres.fields import ArrayField +from django.conf import settings + +from users.models import User + + +class Portfolio(BaseModel): + name = models.CharField(max_length=20) + category = ArrayField(models.CharField(max_length=20), default=list) + is_published = models.BooleanField(default=False) + view_count = models.IntegerField(default=0) + like_count = models.IntegerField(default=0) + scrab_count = models.IntegerField(default=0) + is_represent = models.BooleanField(default=False) + code_id = models.CharField(max_length=26, blank=True) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='portfolios', to_field="id") \ No newline at end of file From 0f5baeb9eb8774ea8e14217a6425e6fab3a08ce2 Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:58:54 +0900 Subject: [PATCH 09/10] =?UTF-8?q?=E2=9C=A8=20Feat:=20[#10]=20codes=20?= =?UTF-8?q?=EC=95=B1=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=B4=88=EB=8C=80?= =?UTF-8?q?/=EC=9D=B8=EC=A6=9D=EC=BD=94=EB=93=9C=20=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- codes/__init__.py | 0 codes/admin.py | 3 +++ codes/apps.py | 6 ++++++ codes/models.py | 19 +++++++++++++++++++ codes/tests.py | 3 +++ codes/views.py | 3 +++ 6 files changed, 34 insertions(+) create mode 100644 codes/__init__.py create mode 100644 codes/admin.py create mode 100644 codes/apps.py create mode 100644 codes/models.py create mode 100644 codes/tests.py create mode 100644 codes/views.py diff --git a/codes/__init__.py b/codes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/codes/admin.py b/codes/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/codes/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/codes/apps.py b/codes/apps.py new file mode 100644 index 0000000..5238a21 --- /dev/null +++ b/codes/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class CodesConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'codes' diff --git a/codes/models.py b/codes/models.py new file mode 100644 index 0000000..b95593f --- /dev/null +++ b/codes/models.py @@ -0,0 +1,19 @@ +from django.db import models + +from common.models.baseModels import BaseModel +from common.models.choiceModels import CertificateCodeUseType, InviteCodeUseType +from common.utils.codeManger import set_expire + + +class CertificationCode(BaseModel): + use_type = models.CharField(choices=CertificateCodeUseType.choices, max_length=5) + code = models.CharField(max_length=6) + expire_at = models.DateTimeField(default=set_expire(minutes=5)) + is_used = models.BooleanField(default=False) + identifier = models.CharField(max_length=40) + +class InviteCode(BaseModel): + use_type = models.CharField(choices=InviteCodeUseType.choices, max_length=5) + code = models.CharField(max_length=10) + expire_at = models.DateTimeField(default=set_expire(minutes=10080)) # 일주일은 10080분 + identifier = models.CharField(max_length=40) diff --git a/codes/tests.py b/codes/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/codes/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/codes/views.py b/codes/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/codes/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. From 5d4eb90a8d8d288e5d5e082b7fe904a8617eb7ee Mon Sep 17 00:00:00 2001 From: sm4640 Date: Thu, 27 Mar 2025 16:59:55 +0900 Subject: [PATCH 10/10] =?UTF-8?q?=F0=9F=94=A7=20Settings:=20settings.py?= =?UTF-8?q?=EC=97=90=20=EC=95=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/settings.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/settings.py b/config/settings.py index d2ae3d5..bdd23db 100644 --- a/config/settings.py +++ b/config/settings.py @@ -44,7 +44,9 @@ INSTALLED_APPS = [ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django.contrib.postgres', 'django_apscheduler', + 'django_extensions', 'rest_framework', 'rest_framework_simplejwt', 'rest_framework_simplejwt.token_blacklist', @@ -52,6 +54,7 @@ INSTALLED_APPS = [ 'users', 'portfolios', 'projects', + 'codes', ] MIDDLEWARE = [