Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ venv
db.sqlite3
migrations
! migrations/__init__.py
.DS_Store
.DS_Store
static
4 changes: 2 additions & 2 deletions django/django_projects/lionapp/urls.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from django.contrib import admin
from django.urls import path
from . import views

Expand All @@ -8,5 +7,6 @@
path('delete/<int:pk>',views.delete_post),
path('comments/<int:post_id>',views.get_comment), # 주소뒤에 붙을 이름/pk값,views에 선언한 함수명
path('v2/post/<int:pk>',views.PostApiView.as_view()),
path('v2/post',views.create_post_v2)
path('v2/post',views.create_post_v2),
path('', views.index, name='index'),
]
105 changes: 97 additions & 8 deletions django/django_projects/lionapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,29 @@
from .models import *
from rest_framework.response import Response
import json
from drf_yasg.utils import swagger_auto_schema
from rest_framework.decorators import authentication_classes
from rest_framework_simplejwt.authentication import JWTAuthentication


@swagger_auto_schema(
method="POST",
tags=["첫번째 view"],
operation_summary="post 생성",
operation_description="post를 생성합니다.",
responses={
201: '201에 대한 설명',
400: '400에 대한 설명',
500: '500에 대한 설명'
}
)
@authentication_classes([JWTAuthentication])
@api_view(['POST'])
def create_post (request) :
if request.method == 'POST':
data = json.loads(request.body)

title = data.get('title'),
title = data.get('title')
content = data.get('content')

post = Post(
Expand All @@ -25,6 +42,20 @@ def create_post (request) :
return JsonResponse({'message':'성공적입니다. 살았어요!'})
return JsonResponse({'message':'POST 요청만 허용됩니다.'})

#하나의 스웨거당 하나의 함수가 세트로 붙는 것.
@swagger_auto_schema(
method="POST",
tags=["두번째 view"],
operation_summary="post 생성",
operation_description="post를 생성합니다.",
responses={
201: '201에 대한 설명',
400: '400에 대한 설명',
500: '500에 대한 설명'
}
)
@authentication_classes([JWTAuthentication])
@api_view(['POST'])
def get_post(request, pk):
post = get_object_or_404(Post, pk=pk)
data = {
Expand All @@ -35,6 +66,19 @@ def get_post(request, pk):
}
return JsonResponse(data, status=200)

@swagger_auto_schema(
method="DELETE",
tags=["첫번째 view"],
operation_summary="post 생성",
operation_description="post를 생성합니다.",
responses={
201: '201에 대한 설명',
400: '400에 대한 설명',
500: '500에 대한 설명'
}
)
@authentication_classes([JWTAuthentication])
@api_view(['DELETE'])
def delete_post(request, pk):
if request.method == 'DELETE':
post = get_object_or_404(Post, pk=pk)
Expand All @@ -45,20 +89,45 @@ def delete_post(request, pk):
return JsonResponse(data, status=200)
return JsonResponse({'message':'DELETE 요청만 허용됩니다.'})


@swagger_auto_schema(
method="GET",
tags=["첫번째 view"],
operation_summary="post 생성",
operation_description="post를 생성합니다.",
responses={
201: '201에 대한 설명',
400: '400에 대한 설명',
500: '500에 대한 설명'
}
)
@authentication_classes([JWTAuthentication])
@api_view(['GET'])
def get_comment(request, post_id): #post에 대한 comment 가져오는 api
if request.method == 'GET':
post = get_object_or_404(Post, pk=post_id)
comment_list = post.commentss.all()
return HttpResponse(comment_list, status=200) #200 - 서버가 요청을 제대로 처리했다는 뜻

comment_list = list(post.commentss.all().values()) # 댓글 목록을 JSON 직렬화 가능한 형식으로 변환
return JsonResponse({'comments': comment_list}, status=200) #200 - 서버가 요청을 제대로 처리했다는 뜻


def api_response(data, message, status):
response = {
"message":message,
"data": data
}
return Response(response, status=status) # 앞에 status는 Response의 것, 뒤에는 api_response 것.

@swagger_auto_schema(
method="POST",
tags=["첫번째 view"],
operation_summary="post 생성",
operation_description="post를 생성합니다.",
responses={
201: '201에 대한 설명',
400: '400에 대한 설명',
500: '500에 대한 설명'
}
)
@authentication_classes([JWTAuthentication])
@api_view(['POST'])
def create_post_v2(request):
post = Post(
Expand All @@ -70,15 +139,16 @@ def create_post_v2(request):
message = f"id: {post.pk}번 포스트 생성 성공이다욧"
return api_response(data = None,message = message, status = status.HTTP_201_CREATED)

class PostApiView(APIView):

class PostApiView(APIView):
authentication_classes = [JWTAuthentication]

def get_object(self, pk): #클래스에서는 self 필수, 여기서 get object를 쓰겠다.
post = get_object_or_404(Post, pk=pk)
return post

def get(self, request, pk):
post = self.get_object(pk)

postSerializer = PostSerializer(post) #여기에 넣어주면 객체를 직렬화 과정을 통해 json 형식으로 변경해줌.
message = f"id: {post.pk}번 포스트 조회 성공"
return api_response(data = postSerializer.data, message = message, status = status.HTTP_200_OK)
Expand All @@ -88,4 +158,23 @@ def delete(self, request, pk):
post.delete()

message = f"id: {pk}번 포스트 삭제 성공"
return api_response(data = None, message = message, status = status.HTTP_200_OK)
return api_response(data = None, message = message, status = status.HTTP_200_OK)

@swagger_auto_schema(
method="POST",
tags=["첫번째 view"],
operation_summary="post 생성",
operation_description="post를 생성합니다.",
responses={
201: '201에 대한 설명',
400: '400에 대한 설명',
500: '500에 대한 설명'
}
)
@authentication_classes([JWTAuthentication])
@api_view(['GET', 'POST'])
def index(request):
if request.method == 'POST':
return HttpResponse("Post method")
else:
return HttpResponse("Get method")
2 changes: 2 additions & 0 deletions django/django_projects/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ requests==2.31.0
sqlparse==0.4.4
urllib3==2.2.1
virtualenv==20.25.1
drf-yasg==1.21.7
setuptools==70.0.0
101 changes: 74 additions & 27 deletions django/django_projects/seminar_project/settings.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,39 @@
"""
Django settings for seminar_project project.

Generated by 'django-admin startproject' using Django 5.0.3.

For more information on this file, see
https://docs.djangoproject.com/en/5.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/5.0/ref/settings/
"""

from pathlib import Path
from datetime import timedelta
import os

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# -> 현재 파일의 디렉토리 경로를 기준으로 상위 디렉토리를 참조하여 프로젝트의 기본 디렉토리를 설정


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-le88gilp)+kp94%wmhay!(nk!u^6orjkipr9k0u09fjp4a_38c'
# -> Django 애플리케이션의 보안에 사용되는 비밀 키로, 애플리케이션의 보안을 강화하기 위한 키입니다!
# 실제 프로젝트에서는 노출되어서는 안되는 키입니다!

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# -> 디버그 모드를 설정하며, 개발 중에는 True로 유지하여 디버깅 정보를 보여준다.어디서 에러가 나오는지.

ALLOWED_HOSTS = ["*"]

# 허용된 호스트의 목록으로, 배포 환경에서 웹 애플리케이션이 서비스하는 도메인을 설정한다

# Application definition

INSTALLED_APPS = [
# my app
'util',
'lionapp',
'users',
# third party app
'rest_framework',
'corsheader',
'rest_framework_simplejwt',
'drf_yasg',
'corsheaders',
# Basic App
'django.contrib.admin',
'django.contrib.auth',
Expand All @@ -56,6 +53,37 @@
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# -> Django 미들웨어의 목록으로, 요청과 응답 처리 사이에 동작하는 기능들을 제어합니다.


# 인증 인가와 커스텀 유저

AUTH_USER_MODEL = 'users.User' # 커스텀 유저를 장고에서 사용하기 위함

REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated', # 인증된 요청인지 확인
#'rest_framework.permissions.AllowAny', # 누구나 접근 가능
# (기본적으로 누구나 접근 가능하게 설정하고, 인증된 요청인지 확인하는 api를 따로 지정하게 하려면
# 이 옵션을 위의 옵션 대신 켜주어도 됩니다!)
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication', # JWT를 통한 인증방식 사용
),
} # Django REST framework 설정으로, API의 권한 및 인증 방식을 설정합니다.

REST_USE_JWT = True # JWT를 기본 인증 방식으로 사용하도록 설정

SIMPLE_JWT = { # JWT 설정으로, JSON Web Token의 특정 속성을 설정합니다.
'SIGNING_KEY': 'hellolikelionhellolikelion', #숨겨줘야하는 값임
# JWT에서 가장 중요한 인증키입니다!
# 이 키가 알려지게 되면 JWT의 인증체계가 다 털릴 수 있으니 노출되지 않게 조심해야합니다!
'ACCESS_TOKEN_LIFETIME': timedelta(hours=1), #access 토큰 유효기간 1시간
'REFRESH_TOKEN_LIFETIME': timedelta(days=7), # refresh 토큰 유효기간 7일
'ROTATE_REFRESH_TOKENS': False, # True로 설정하면 리프레시 토큰이 사용될 때마다 새로운 리프레시 토큰이 발급됩니다.
'BLACKLIST_AFTER_ROTATION': True, # 리프레시 토큰 회전 후, 이전의 리프레시 토큰이 블랙리스트에 추가될지 여부를 나타내는 부울 값입니다.
# True로 설정하면 리프레시 토큰이 회전되면서, 이전의 리프레시 토큰은 블랙리스트에 추가되어 더 이상 사용할 수 없게 됩니다.
}

#CORS

Expand All @@ -82,11 +110,11 @@
'x-requested-with',
]

CORS_ALLOW_ALL_ORIGINS = [
'https://chiikawaworld.o-r.kr/',
]
CORS_ALLOW_ALL_ORIGINS = True

ROOT_URLCONF = 'seminar_project.urls'
# -> 프로젝트의 최상위 URL 설정 파일을 지정합니다.
# (따라서 url은 seminar_project의 urls.py 파일을 항상 먼저 보는 것입니다!)

TEMPLATES = [
{
Expand All @@ -102,9 +130,10 @@
],
},
},
]
] # admin 페이지를 구성할 때 필요합니다!

WSGI_APPLICATION = 'seminar_project.wsgi.application'
# -> 프로젝트의 WSGI 애플리케이션을 지정합니다.

# Database
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
Expand All @@ -114,7 +143,7 @@
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
} # 데이터베이스 연결 설정으로, 현재는 SQLite를 사용하고 있습니다.


# Password validation
Expand All @@ -123,17 +152,17 @@
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
},# 사용자의 아이디와 유사한 비밀번호를 허용하지 않음
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
},# 비밀번호가 설정된 길이 보다 짧지 않도록 검사
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
},# 널리 사용되는 암호 목록과 일치하는 비밀번호를 거부합니다. 널리 사용되는 암호를 피하고 보안을 강화합니다. (이거 찾아보면 금지해놓은 재밌는 암호들이 많았던 것으로 기억합니다...ㅋㅋ)
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
},# 비밀번호에 숫자가 포함되어 있는지 확인하여, 숫자를 사용하도록 유도합니다.
] # 비밀번호 유효성 검사기 설정으로, 사용자 비밀번호의 강도를 제어합니다.


# Internationalization
Expand All @@ -144,16 +173,34 @@
TIME_ZONE = 'Asia/Seoul'

USE_I18N = True

USE_TZ = True
# 국제화 및 시간대 사용 여부를 설정합니다. 웬만하면 그대로 두시는 것을 추천합니다!


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.0/howto/static-files/

STATIC_URL = 'static/'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR,'static')
# 정적 파일(사진 같은..)의 URL을 설정합니다.

# Default primary key field type
# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# 기본 자동 생성 필드를 생성합니다.

SWAGGER_SETTINGS = {
'USE_SESSION_AUTH': False,
'SECURITY_DEFINITIONS': {
'BearerAuth': {
'type': 'apiKey',
'name': 'Authorization',
'in': 'header',
'description': "JWT Token"
}
},
'SECURITY_REQUIREMENTS': [{
'BearerAuth': []
}]
}
Loading