WinGyu_coder
Python, Django 장고로 모의투자 서비스 제작하기 (6) - Python으로 Django DB에 데이터 저장하기 본문
Python, Django 장고로 모의투자 서비스 제작하기 (6) - Python으로 Django DB에 데이터 저장하기
WinGyu 2024. 3. 2. 17:35Python, Django 장고로 모의투자 서비스 제작하기 (5) - Django models.py 모델 필드 정의하기
이전 포스트:
https://wingyu-story.tistory.com/134
깃허브 주소 :
https://github.com/decembaek/auto_stock_django
이번에는 드디어 Django models.py를 정의했으니,, 정의한 모델을 통해 DB에 데이터를 저장할 것이다.
엑셀 데이터는 포스트 목록에 올라와 있다,,
자 저번 포스트까지 모델.py 를 정의했는데, 한개 더 추가해주자
# 주식 기본 정보 모델
class StockInfoModel(models.Model):
stock_code = models.ForeignKey(StockCodeModel, on_delete=models.CASCADE, null=True)
tr_id = models.CharField(default="", max_length=100) # 요청한 tr_id
rt_cd = models.CharField(default="", max_length=2) # 성공여부
msg_cd = models.CharField(default="", max_length=20) # 응답코드
msg1 = models.CharField(default="", max_length=150) # 응답 메세지
# output = models.TextField(default="") # 응답 상세1
pdno = models.CharField(default="", max_length=100) # 상품번호
prdt_type_cd = models.CharField(default="", max_length=20) # 상품유형코드
mket_id_cd = models.CharField(default="", max_length=20) # 시장 ID 코드
scty_grp_id_cd = models.CharField(default="", max_length=20) # 증권그룹ID 코드
excg_dvsn_cd = models.CharField(default="", max_length=20) # 거래소구분코드
setl_mmdd = models.CharField(default="", max_length=10) # 결산월일
lstg_stqt = models.CharField(default="", max_length=50) # 상장주수
lstg_cptl_amt = models.CharField(default="", max_length=50) # 상장 자본 금액
cpta = models.CharField(default="", max_length=50) # 자본금
papr = models.CharField(default="", max_length=50) # 액면가
issu_pric = models.CharField(default="", max_length=50) # 발행가격
kospi200_item_yn = models.CharField(
default="", max_length=50
) # 코스피 200 종목 여부
scts_mket_lstg_dt = models.CharField(
default="", max_length=50
) # 유가증권시장상장일자
scts_mket_lstg_abol_dt = models.CharField(
default="", max_length=50
) # 유가증권시장 상장폐지 일자
kosdaq_mket_lstg_dt = models.CharField(
default="", max_length=50
) # 코스닥 시장 상장 일자
kosdaq_mket_lstg_abol_dt = models.CharField(
default="", max_length=50
) # 코스닥 시장 상장 폐지 일자
frbd_mket_lstg_dt = models.CharField(
default="", max_length=50
) # 프리보드시장 상장일자
frbd_mket_lstg_abol_dt = models.CharField(
default="", max_length=50
) # 프로비도시장 상장폐지 일자
reits_kind_cd = models.CharField(default="", max_length=50) # 리츠종류코드
etf_dvsn_cd = models.CharField(default="", max_length=50) # ETF구분코드
oilf_fund_yn = models.CharField(default="", max_length=50) # 유전펀드여부
idx_bztp_lcls_cd = models.CharField(
default="", max_length=50
) # 지수업종대부류 코드
idx_bztp_mcls_cd = models.CharField(
default="", max_length=50
) # 지수업종중분류 코드
idx_bztp_scls_cd = models.CharField(
default="", max_length=50
) # 지수업종소분류 코드
stck_kind_cd = models.CharField(default="", max_length=50) # 주식종류코드
mfnd_opng_dt = models.CharField(default="", max_length=50) # 뮤추얼펀드 개시일자
mfnd_end_dt = models.CharField(default="", max_length=50) # 뮤추얼펀드 종료일자
dpsi_erlm_cncl_dt = models.CharField(default="", max_length=50) # 예탁등록취소 일자
etf_cu_qty = models.CharField(default="", max_length=50) # ETFCU 수량
prdt_name = models.CharField(default="", max_length=100) # 상품명
prdt_name120 = models.CharField(default="", max_length=300) # 상품명 120
prdt_abrv_name = models.CharField(default="", max_length=200) # 상품약어명
std_pdno = models.CharField(default="", max_length=50) # 표준상품번호
prdt_eng_name = models.CharField(default="", max_length=100) # 상품영문명
prdt_eng_name120 = models.CharField(default="", max_length=300) # 상품영문명120
prdt_eng_abrv_name = models.CharField(default="", max_length=100) # 상품영문약어명
dpsi_aptm_erlm_yn = models.CharField(default="", max_length=10) # 예탁지정등록여부
etf_txtn_type_cd = models.CharField(default="", max_length=100) # ETF 과세유형코드
etf_type_cd = models.CharField(default="", max_length=100) # ETF 유형코드
lstg_abol_dt = models.CharField(default="", max_length=10) # 상장폐지일자
nwst_odst_dvsn_cd = models.CharField(
default="", max_length=100
) # 신주구주구분 코드
sbst_pric = models.CharField(default="", max_length=100) # 대용가격
thco_sbst_pric = models.CharField(default="", max_length=100) # 당사 대용가격
thco_sbst_pric_chng_dt = models.CharField(
default="", max_length=100
) # 당사 대용가격 변경일자
tr_stop_yn = models.CharField(default="", max_length=100) # 거래 정지여부
admn_item_yn = models.CharField(default="", max_length=100) # 관리종목여부
thdt_clpr = models.CharField(default="", max_length=100) # 당일종가
bfdy_clpr = models.CharField(default="", max_length=100) # 전일종가
clpr_chng_dt = models.CharField(default="", max_length=100) # 종가변경일자
std_idst_clsf_cd = models.CharField(default="", max_length=100) # 표준산업분류코드
sstd_idst_clsf_code = models.ForeignKey(
KSICCodeModel, on_delete=models.CASCADE, null=True
) # 표준산업분류코드 FK
std_idst_clsf_cd_name = models.CharField(
default="", max_length=300
) # 표준산업분류 코드명
idx_bztp_lcls_cd_name = models.CharField(
default="", max_length=200
) # 지수업종대분류 코드명
idx_bztp_mcls_cd_name = models.CharField(
default="", max_length=200
) # 지수업종중분류 코드명
idx_bztp_scls_cd_name = models.CharField(
default="", max_length=200
) # 지수업종소분류 코드명
ocr_no = models.CharField(default="", max_length=10) # OCR 번호
crfd_item_yn = models.CharField(default="", max_length=10) # 크라우드펀딩 종목여부
elec_scty_yn = models.CharField(default="", max_length=10) # 전자증권여부
updated_at = models.DateTimeField(auto_now=True) # update time
각 필드는 친절하게 설명 주석을 달아두었다.
이제 DB에 이 필드들을 정의할거다.
아래 명령어를 써주자,
python manage.py makemigrations
python manage.py migrate
위에는 마이그레이션 파일들을 생성하는거고, 아래 migrate는 이 파일을 토대로 DB를 정의한다.
쉽게 생각하면 위에는 DB 구성을 파일로 만든거다, 유저 정보를 정의했다면, 유저 이름, 성, 전화번호 등 정보가 필요할텐데,
그 구성을 마이그레이션 파일을 생성하고, migrate 는 적용하는거다.
명령어를 오류없이 정상적으로 작동했다면, 이제 아래와 같이 코드를 작성하자.
가장 중요한 주식 종목코드 데이터 저장 파이썬파일이다.
korea_stock_info_data.py
국내주식 정보에 대한 파이썬 파일이다.
"""
kospi, kosdap 종목 정보 info 데이터 넣기
"""
import os
from pathlib import Path
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
django.setup()
# 시크릿 키 숨기기 django-environ
# Django-environ 설치하고 사용하기 !
# import environ
import pandas as pd
from korea_stock.models import StockInfoModel, KSICCodeModel, StockCodeModel
from dotenv import load_dotenv
load_dotenv()
# env = environ.Env()
import json
import requests
import time
# TEST_KEY = os.environ.get("TEST_APP_KEY")
# TEST_SECRET = os.environ.get("TEST_APP_SECRET")
APP_KEY = os.environ.get("APP_KEY")
APP_SECRET = os.environ.get("APP_SECRET")
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
REAL_URL_BASE = "https://openapi.koreainvestment.com:9443"
# TEST_URL_BASE = "https://openapivts.koreainvestment.com:29443"
REALTIME_WEBSOCKET_URL = "/oauth2/Approval"
# HASH_KEY_URL = "/uapi/hashkey"
TOKEN_URL = "/oauth2/tokenP"
# PRICE_NOW_URL = "/uapi/domestic-stock/v1/quotations/inquire-price"
STOCK_INFO_URL = "/uapi/domestic-stock/v1/quotations/search-stock-info"
json_headers = {"content-type": "application/json"}
token_body = {
"grant_type": "client_credentials",
"appkey": APP_KEY,
"appsecret": APP_SECRET,
}
# TOKEN 발급이 필요하면 True로 하기
token_bool = False
if token_bool:
token_res = requests.post(
REAL_URL_BASE + TOKEN_URL,
headers=json_headers,
data=json.dumps(token_body),
# timeout 요청 시간 제한
timeout=10,
)
ACCESS_TOKEN = token_res.json()["access_token"]
# JSON 파일로 저장
with open("ACCESS_TOKEN.json", "w") as json_file:
json.dump({"ACCESS_TOKEN": ACCESS_TOKEN}, json_file, indent=4)
else:
with open("ACCESS_TOKEN.json", "r") as json_file:
data = json.load(json_file)
ACCESS_TOKEN = data["ACCESS_TOKEN"]
print(ACCESS_TOKEN)
headers = {
"content-type": "application/json",
"authorization": "Bearer " + ACCESS_TOKEN,
"appkey": APP_KEY,
"appsecret": APP_SECRET,
"tr_id": "CTPF1002R",
"custtype": "P",
}
params = {
"PRDT_TYPE_CD": "300",
"PDNO": None,
}
all_code = StockCodeModel.objects.all()
for code in all_code:
code_num = code.code
params["PDNO"] = code_num
res = requests.get(
REAL_URL_BASE + STOCK_INFO_URL,
headers=headers,
params=params,
timeout=10,
)
result = res.json()
print(code_num)
output = result["output"]
ksic = output["std_idst_clsf_cd"]
print(ksic)
try:
ksic_model = KSICCodeModel.objects.get(ksic_code=ksic)
except:
ksic_model = None
print(ksic_model)
StockInfoModel.objects.create(
stock_code=code,
tr_id="CTPF1002R",
rt_cd=result["rt_cd"],
msg_cd=result["msg_cd"],
msg1=result["msg1"],
# output
pdno=output["pdno"],
prdt_type_cd=output["prdt_type_cd"],
mket_id_cd=output["mket_id_cd"],
scty_grp_id_cd=output["scty_grp_id_cd"],
excg_dvsn_cd=output["excg_dvsn_cd"],
setl_mmdd=output["setl_mmdd"],
lstg_stqt=output["lstg_stqt"],
lstg_cptl_amt=output["lstg_cptl_amt"],
cpta=output["cpta"],
papr=output["papr"],
issu_pric=output["issu_pric"],
kospi200_item_yn=output["kospi200_item_yn"],
scts_mket_lstg_dt=output["scts_mket_lstg_dt"],
scts_mket_lstg_abol_dt=output["scts_mket_lstg_abol_dt"],
kosdaq_mket_lstg_dt=output["kosdaq_mket_lstg_dt"],
kosdaq_mket_lstg_abol_dt=output["kosdaq_mket_lstg_abol_dt"],
frbd_mket_lstg_dt=output["frbd_mket_lstg_dt"],
frbd_mket_lstg_abol_dt=output["frbd_mket_lstg_abol_dt"],
reits_kind_cd=output["reits_kind_cd"],
etf_dvsn_cd=output["etf_dvsn_cd"],
oilf_fund_yn=output["oilf_fund_yn"],
idx_bztp_lcls_cd=output["idx_bztp_lcls_cd"],
idx_bztp_mcls_cd=output["idx_bztp_mcls_cd"],
idx_bztp_scls_cd=output["idx_bztp_scls_cd"],
stck_kind_cd=output["stck_kind_cd"],
mfnd_opng_dt=output["mfnd_opng_dt"],
mfnd_end_dt=output["mfnd_end_dt"],
dpsi_erlm_cncl_dt=output["dpsi_erlm_cncl_dt"],
etf_cu_qty=output["etf_cu_qty"],
prdt_name=output["prdt_name"],
prdt_name120=output["prdt_name120"],
prdt_abrv_name=output["prdt_abrv_name"],
std_pdno=output["std_pdno"],
prdt_eng_name=output["prdt_eng_name"],
prdt_eng_name120=output["prdt_eng_name120"],
prdt_eng_abrv_name=output["prdt_eng_abrv_name"],
dpsi_aptm_erlm_yn=output["dpsi_aptm_erlm_yn"],
etf_txtn_type_cd=output["etf_txtn_type_cd"],
etf_type_cd=output["etf_type_cd"],
lstg_abol_dt=output["lstg_abol_dt"],
nwst_odst_dvsn_cd=output["nwst_odst_dvsn_cd"],
sbst_pric=output["sbst_pric"],
thco_sbst_pric=output["thco_sbst_pric"],
thco_sbst_pric_chng_dt=output["thco_sbst_pric_chng_dt"],
tr_stop_yn=output["tr_stop_yn"],
admn_item_yn=output["admn_item_yn"],
thdt_clpr=output["thdt_clpr"],
bfdy_clpr=output["bfdy_clpr"],
clpr_chng_dt=output["clpr_chng_dt"],
std_idst_clsf_cd=output["std_idst_clsf_cd"],
sstd_idst_clsf_code=ksic_model, # FKey
std_idst_clsf_cd_name=output["std_idst_clsf_cd_name"],
idx_bztp_lcls_cd_name=output["idx_bztp_lcls_cd_name"],
idx_bztp_mcls_cd_name=output["idx_bztp_mcls_cd_name"],
idx_bztp_scls_cd_name=output["idx_bztp_scls_cd_name"],
ocr_no=output["ocr_no"],
crfd_item_yn=output["crfd_item_yn"],
elec_scty_yn=output["elec_scty_yn"],
)
print("complete")
코드가 너무 길다고 겁 먹지말자, 구글 소스코드는 14억줄이 넘는 코드가 있다고 들었다. (지금은 훨씬 많이 늘었을거 같다)
맨 위에 코드부터 설명해보겠다.
"""
kospi, kosdap 종목 정보 info 데이터 넣기
"""
import os
from pathlib import Path
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
django.setup()
# 시크릿 키 숨기기 django-environ
# Django-environ 설치하고 사용하기 !
# import environ
import pandas as pd
from korea_stock.models import StockInfoModel, KSICCodeModel, StockCodeModel
from dotenv import load_dotenv
load_dotenv()
# env = environ.Env()
import json
import requests
import time
자 우선 각설하고 모듈부터 시작해보자.
맨위에
import os
from pathlib import Path
import django
이렇게 보인다.
일단 맥북을 사용하면서 OS 별로 경로 문제가 생기는데
from pathlib import Path 그걸 위한 모듈들이다 ( 현재 Path 코드는 쓰지 않는다) 사실상 필요없다.
import os 와 import django 는 말 그대로 시스템 설정 및 장고를 가져오는거다.
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
django.setup()
os 모듈을 사용해 장고 config settings 파일을 불러온다 ( Django 에서 settings 파일은 사람으로 따지면 머리라 할 수 있다.)
그리고 django.setup() 명령어를 써주면 이 python 스크립트 파일은 이제 django를 사용 할 수 있다.
import pandas as pd
from korea_stock.models import StockInfoModel, KSICCodeModel, StockCodeModel
from dotenv import load_dotenv
load_dotenv()
# env = environ.Env()
import json
import requests
import time
위 부터 간단 설명하자면
pandas 모듈로 Date관련 데이터라든지,,데이터 분석 및 관리에 많이 쓰이는 모듈이다.
2번쨰 줄은 모델을 가져오는 모듈로 모델들을 가져오고 저걸 통해 데이터를 저장할거다.
from dotenv import load_dotenv
load_dotenv()
는 보안관련 떄문에 추가한 코드다, 필요하지 않지만 필자 처럼 깃허브로 프로젝트를 관리하거나, 보안에 민감하면 쓰는걸 추천한다.
이 코드는 .env 에서 보안키 및 시크릿키를 가져온다..
import json -> json 사용 모듈
import requests -> api 등 네트워크 요청 모듈
import time -> 시간 관련 모듈
이정도면 모듈은 끝났다. 구글링하면 아주 자세히 나온다.
그다음 한국투자증권 API 코드다
APP_KEY = os.environ.get("APP_KEY")
APP_SECRET = os.environ.get("APP_SECRET")
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
REAL_URL_BASE = "https://openapi.koreainvestment.com:9443"
# TEST_URL_BASE = "https://openapivts.koreainvestment.com:29443"
REALTIME_WEBSOCKET_URL = "/oauth2/Approval"
# HASH_KEY_URL = "/uapi/hashkey"
TOKEN_URL = "/oauth2/tokenP"
# PRICE_NOW_URL = "/uapi/domestic-stock/v1/quotations/inquire-price"
STOCK_INFO_URL = "/uapi/domestic-stock/v1/quotations/search-stock-info"
json_headers = {"content-type": "application/json"}
token_body = {
"grant_type": "client_credentials",
"appkey": APP_KEY,
"appsecret": APP_SECRET,
}
# TOKEN 발급이 필요하면 True로 하기
token_bool = False
if token_bool:
token_res = requests.post(
REAL_URL_BASE + TOKEN_URL,
headers=json_headers,
data=json.dumps(token_body),
# timeout 요청 시간 제한
timeout=10,
)
ACCESS_TOKEN = token_res.json()["access_token"]
# JSON 파일로 저장
with open("ACCESS_TOKEN.json", "w") as json_file:
json.dump({"ACCESS_TOKEN": ACCESS_TOKEN}, json_file, indent=4)
else:
with open("ACCESS_TOKEN.json", "r") as json_file:
data = json.load(json_file)
ACCESS_TOKEN = data["ACCESS_TOKEN"]
print(ACCESS_TOKEN)
차근차근 읽어보면 알겠지만,
한국투자증권 API 문서에 맞게 URL을 미리 변수에 지정해두었고, 비밀 키 같은건 .env 파일에 숨겨두었다.
ACCESS_TOKEN 같은 경우 한국투자증권 문서를 읽어보면 알겠지만 하루에 1번 키 요청을 권장하고 여러번 요청시 차단이 될 수도 있다는 문서 내용을 봤다. 그래서 필자같은경우 필요할때만 요청할려고 If 문을 추가해두었고 한 번 요청했으면 json 파일로 저장시켜 다시 가져올 수 있게 해두었다.
자 이제 본격적인 데이터 저장 로직이다.
all_code = StockCodeModel.objects.all()
장고는 ORM 을 지원하는 아주 대단한 프레임워크다,, 필자가 가장 좋아하는 프레임워크가 DJango 장고이다,
위 한줄만으로 StockCodeModel에 모든 데이터를 가져올 수 있다.
생각을 해봤는데 StockCodeModel에 엑셀로 데이터 넣는 방법 포스트를 아직 안 했다. 바보같이,,
"""
급하게 업로드 했다.
https://wingyu-story.tistory.com/136
위 포스트에 들어가면 엑셀 3가지 파일을 DB에 저장하는 코드를 담아 두었다.
"""
자 그럼 국내주식 KOSPI, KOSDAQ 모든 종목을 가져왔으니 다시 이어서 해보자
모든 주식을 위 변수 all_code에 저장했다면 이제 완벽하다
for code in all_code:
code_num = code.code
params["PDNO"] = code_num
res = requests.get(
REAL_URL_BASE + STOCK_INFO_URL,
headers=headers,
params=params,
timeout=10,
)
result = res.json()
print(code_num)
output = result["output"]
ksic = output["std_idst_clsf_cd"]
print(ksic)
try:
ksic_model = KSICCodeModel.objects.get(ksic_code=ksic)
except:
ksic_model = None
print(ksic_model)
StockInfoModel.objects.create(
stock_code=code,
tr_id="CTPF1002R",
rt_cd=result["rt_cd"],
msg_cd=result["msg_cd"],
msg1=result["msg1"],
# output
pdno=output["pdno"],
prdt_type_cd=output["prdt_type_cd"],
mket_id_cd=output["mket_id_cd"],
scty_grp_id_cd=output["scty_grp_id_cd"],
excg_dvsn_cd=output["excg_dvsn_cd"],
setl_mmdd=output["setl_mmdd"],
lstg_stqt=output["lstg_stqt"],
lstg_cptl_amt=output["lstg_cptl_amt"],
cpta=output["cpta"],
papr=output["papr"],
issu_pric=output["issu_pric"],
kospi200_item_yn=output["kospi200_item_yn"],
scts_mket_lstg_dt=output["scts_mket_lstg_dt"],
scts_mket_lstg_abol_dt=output["scts_mket_lstg_abol_dt"],
kosdaq_mket_lstg_dt=output["kosdaq_mket_lstg_dt"],
kosdaq_mket_lstg_abol_dt=output["kosdaq_mket_lstg_abol_dt"],
frbd_mket_lstg_dt=output["frbd_mket_lstg_dt"],
frbd_mket_lstg_abol_dt=output["frbd_mket_lstg_abol_dt"],
reits_kind_cd=output["reits_kind_cd"],
etf_dvsn_cd=output["etf_dvsn_cd"],
oilf_fund_yn=output["oilf_fund_yn"],
idx_bztp_lcls_cd=output["idx_bztp_lcls_cd"],
idx_bztp_mcls_cd=output["idx_bztp_mcls_cd"],
idx_bztp_scls_cd=output["idx_bztp_scls_cd"],
stck_kind_cd=output["stck_kind_cd"],
mfnd_opng_dt=output["mfnd_opng_dt"],
mfnd_end_dt=output["mfnd_end_dt"],
dpsi_erlm_cncl_dt=output["dpsi_erlm_cncl_dt"],
etf_cu_qty=output["etf_cu_qty"],
prdt_name=output["prdt_name"],
prdt_name120=output["prdt_name120"],
prdt_abrv_name=output["prdt_abrv_name"],
std_pdno=output["std_pdno"],
prdt_eng_name=output["prdt_eng_name"],
prdt_eng_name120=output["prdt_eng_name120"],
prdt_eng_abrv_name=output["prdt_eng_abrv_name"],
dpsi_aptm_erlm_yn=output["dpsi_aptm_erlm_yn"],
etf_txtn_type_cd=output["etf_txtn_type_cd"],
etf_type_cd=output["etf_type_cd"],
lstg_abol_dt=output["lstg_abol_dt"],
nwst_odst_dvsn_cd=output["nwst_odst_dvsn_cd"],
sbst_pric=output["sbst_pric"],
thco_sbst_pric=output["thco_sbst_pric"],
thco_sbst_pric_chng_dt=output["thco_sbst_pric_chng_dt"],
tr_stop_yn=output["tr_stop_yn"],
admn_item_yn=output["admn_item_yn"],
thdt_clpr=output["thdt_clpr"],
bfdy_clpr=output["bfdy_clpr"],
clpr_chng_dt=output["clpr_chng_dt"],
std_idst_clsf_cd=output["std_idst_clsf_cd"],
sstd_idst_clsf_code=ksic_model, # FKey
std_idst_clsf_cd_name=output["std_idst_clsf_cd_name"],
idx_bztp_lcls_cd_name=output["idx_bztp_lcls_cd_name"],
idx_bztp_mcls_cd_name=output["idx_bztp_mcls_cd_name"],
idx_bztp_scls_cd_name=output["idx_bztp_scls_cd_name"],
ocr_no=output["ocr_no"],
crfd_item_yn=output["crfd_item_yn"],
elec_scty_yn=output["elec_scty_yn"],
)
print("complete")
이제 정의한 모델에 맞게 데이터를 저장해둔다.
그러면 총 DB에 주식기본정보가 저장되었을 것 이다.
필자 DB
자 기본정보들도 가져와봤으니 다음 포스트는 가장 중요한 주식 가격을 가져올거다.
필자 목표는 년, 달, 주, 일 별로 데이터를 저장하는것이다.
분 단위로도 하고싶은데 서버 비용 이슈로 인해 어려울거 같다.
ㅎㅎㅎ
'Django 백엔드의 모든것' 카테고리의 다른 글
Django, React 장고, 리액트 로그인 인증 통신하기. 풀스택 (0) | 2024.03.29 |
---|---|
Django Python, 장고로 csv, Json 파일 다운로드 구현하기 (0) | 2024.03.05 |
Python, Django 장고로 모의투자 서비스 제작하기 (5 - 1) - Django DB에 엑셀 데이터 넣기 (0) | 2024.03.02 |
Python, Django 장고로 모의투자 서비스 제작하기 (5) - Django models.py 모델 필드 정의하기 (0) | 2024.02.26 |
Python, Django 장고로 모의투자 서비스 제작하기 (3) - Docker 로 Mysql DB 생성하기 (0) | 2024.02.25 |