๋ ธ๋ ์ถ์ฒ ์๋น์ค
- 2022๋ 11์ 2์ผ ~ 11์ 8์ผ
- ํ ํ๋ก์ ํธ (5๋ช )
๋งก์ ์ญํ
- ์ ์ ๊ด๋ฆฌ ๋ฐ ์ถ๊ฐ ๊ธฐ๋ฅ
- Playlist ์์ฑ/์์ /์ญ์ ๋ฐ ์์ธํ์ด์ง ๊ธฐ๋ฅ
- Python 3.10.7
- Django 4.1.3
- DRF 3.14.0
- Django simple JWT 5.2.2
- SQLite
- Vanilla JS
- Element UI
- Notion
- Github
- Slack
- ์ฌ์ฉ์ ํ๊ฒฝ(ํ์๊ฐ์ , ๋ก๊ทธ์ธ, ํ์์ ๋ณด ๊ด๋ฆฌ ๋ฑ)
- ํ๋ ์ด๋ฆฌ์คํธ ์์ฑ, ์์ , ์ญ์ ๊ธฐ๋ฅ ๊ตฌํ(์ฌ์ง ์ ๋ก๋ ๋ฑ)
- ๋๊ธ ๋ฐ ๋ชจ์ฐฝ ์ ๋ก๋, ์ข์์ ๊ธฐ๋ฅ ๊ตฌํ
- ์ฌ์ฉ์ ์ทจํฅ์ ๋ง๋ ์์ ์ถ์ฒ
4. ERD ์ค๊ณ
- ๋ฌธ์ : ๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ ๊ธฐ๋ฅ ๊ตฌํ ์ค ์ด๋ฉ์ผ ์ ์ก ์๋ ๋๋ฆผ
๊ธฐ์กด ์ฝ๋
def send_email(message):
email = EmailMessage(subject=message["email_subject"], body=message["email_body"], to=[message["to_email"]])
email.send()
- ํด๊ฒฐ: ๋ฉํฐ์ค๋ ๋ ์ ์ฉ ํ ์์ ๊ฐ์ค์น๋ฅผ ๋๋ ค ์คํํ์ง ์๋ ๋ค๋ฅธ ์ค๋ ๋๋ฅผ ํผ๋จ๋ ค ์ฌ์ฉ์์๊ฒ ์๋ตํ๋ ๊ฒฝ๋ก๊ฐ ์ค์๊ฐ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์๋ ํฅ์ 2.5s -> 0.1ms
๊ฐ์ ๋ ์ฝ๋
import threading
class EmailThread(threading.Thread):
def __init__(self, email):
self.email = email
threading.Thread.__init__(self)
def run(self):
self.email.send()
def send_email(message):
email = EmailMessage(subject=message["email_subject"], body=message["email_body"], to=[message["to_email"]])
EmailThread(email).start()
- ๋ฌธ์ : ์์ฒญ์ ๋ํ ์ ๋ณด๋ฅผ serializers.py์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ ๋ชจ๋ฆ
- ํด๊ฒฐ: serializer๋ฅผ ๊ฒ์ฆํ ๋ dict๋ก request๋ฅผ ๋๊ฒจ์ฃผ์ด ํด๊ฒฐ
์ฝ๋
#views.py
serializer = ChangePasswordSerializer(user, data=request.data, context={'request': request})
#serializers.py
current_password = self.context.get("request").user.password
- ๋ฌธ์ : drf ์ ํจ์ฑ ๊ฒ์ฆ ๋ก์ง ๊ตฌํ ์๋จ
- ๋ฌธ์ ์ ์์ธ: drf์์ ์ด๋ฏธ ์ ๊ณตํ๋ ์ ํจ์ฑ ๊ฒ์ฆ ๋ก์ง์ด ์๋ ๊ฒ์ผ๋ก ํ์
๊ธฐ์กด ์ฝ๋
#serializers.py
nickname = date.get('nickname')
if nickname == '':
raise serializers.ValidationError(detail={"nickname":"๋๋ค์์ ์๋ ฅํด์ฃผ์ธ์"})
- ํด๊ฒฐ: validate์ปค์คํฐ๋ง์ด์ง ์ unique ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ถ์ผ๋ฉด error message๋ฅผ unique error์ ๋ํ ์ ์ ํด์ค, ๋น๊ฐ๊ณผ ํ๋๊ฐ์ด ๋น์ด์์ผ๋ฉด extra_kwargs๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ๋ณ๊ฒฝํจ(required์ blank์ invlid ์ฌ์ฉ)
๊ฐ์ ๋ ์ฝ๋
#models.py
email = models.EmailField( max_length=255,unique=True, error_messages={'unique': "์ด๋ฏธ ์กด์ฌํ๋ ์ด๋ฉ์ผ ์ฃผ์์
๋๋ค."})
nickname = models.CharField(max_length=15, unique=True, error_messages={'unique': "์ด๋ฏธ ์กด์ฌํ๋ ๋๋ค์์
๋๋ค."})
#serializers.py
extra_kwargs=
{'email': {'error_messages': {
'required': '์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.',
'invalid': '์๋ง์ ํ์์ ์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.',
'blank':'์ด๋ฉ์ผ์ ์
๋ ฅํด์ฃผ์ธ์.',}},
'nickname': {
'error_messages': {
'required': '๋๋ค์์ ์
๋ ฅํด์ฃผ์ธ์.',
'blank':'๋๋ค์์ ์
๋ ฅํด์ฃผ์ธ์',}},}
- ๋ฌธ์ : ์ฃผ์ ์ ์ ์ ๊ฐ๋ฑ์ด ์์ด ์ฝ๊ฒ ๊ฒฐ์ ์ ๋ด๋ฆฌ์ง ๋ชปํ๋ ์ํฉ
- ํด๊ฒฐ: ๊ธฐํ์ค๋ช ๊ณผ ๋ฉ๋ก 100์ ํฌ๋กค๋ง ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ์ฌ ์ค๋ํ์ฌ ๋ฉ๋ ํ ์ฃผ์ ๊ฒฐ์
- ๊นจ๋ฌ์ ์ : ์ถ์์ ์ธ ์์ด๋์ด๋ฅผ ๋ด๋ ๊ฒ๋ณด๋ค ์ ํํ ๋ฐ์ดํฐ์ ์ค๋ช ์ผ๋ก ์ค๋ํ ์ ์๋ค๋ ์
ํฌ๋กค๋ง ์ฝ๋
from urllib.request import urlopen
import pandas as pd
import urllib.request
import urllib.parse
import time
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
driver = webdriver.Chrome('C:/chromedriver_win32/chromedriver.exe') #ํฌ๋กฌ ๋๋ผ์ด๋ฒ ์ ๊ทผ
driver.implicitly_wait(1)
url = 'https://www.melon.com/chart/age/index.htm?chartType=YE&chartGenre=KPOP&chartDate='
year = ['1990','1991','1992','1993','1994','1995','1996','1997','1998','1999', '2000', '2001','2002','2003','2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014', '2015','2016','2017','2018','2019']
#์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๋ด์ ๊ณณ
df = pd.DataFrame()
#test
driver.get(url+year[0]) #์ฐ๋ ์ ํ - ๋ฐ๋ณต๋ฌธ
jenre = [] # ํฐ ๋ฐ๋ณต๋ฌธ ์์
lyrics = []
titles = []
year = []
for i in range(50):
info_list = driver.find_elements_by_css_selector('#lst50 > td:nth-child(4) > div > a') #Top50 ๋ฆฌ์คํธ #Top50 ๋ฆฌ์คํธ
info_list[i].click() #๊ณก์ ๋ณด ์ ํ
time.sleep(2)
#๊ฐ์ฌ ํผ์น๊ธฐ
try:
driver.find_element_by_css_selector('.button_more.arrow_d').click()
time.sleep(2)
except NoSuchElementException: #๊ฐ์ฌ๊ฐ ์๋ ๊ฒฝ์ฐ ํผ์น๊ธฐ ์ํx
pass
#์ฅ๋ฅด, ๊ฐ์ฌ, ๋
ธ๋ ์ ๋ชฉ ํฌ๋กค๋ง
titles.append(driver.find_element_by_css_selector('#downloadfrm > div > div > div.entry > div.info > div.song_name').text)
jenre.append(driver.find_element_by_css_selector('#downloadfrm > div > div > div.entry > div.meta > dl > dd:nth-child(6)').text)
lyrics.append(driver.find_element_by_css_selector('#lyricArea').text)
year.append('1990')
driver.back()
time.sleep(2)
df = pd.DataFrame(zip(year, titles, jenre, lyrics), columns=['year','titles','jenre','lyrics'])
time.sleep(2)
driver.close()
df.to_csv('C:/Users/haeni_kim/Desktop/PROJECT/multi_project/melon_inform.csv',encoding = 'utf-8-sig')
ํ๋ก์ ํธ ๊ฐ๋ฐ ํ๊ณ ๊ธ: https://bolder-starburst-a73.notion.site/221108-9cab6c3034624797b2d3c3179e79c282
ํ๋ก์ ํธ ํํฉํ / ๊ทธ ์ธ ํธ๋ฌ๋ธ ์ํ : https://bolder-starburst-a73.notion.site/0ddbb2be0a474d35a4a957278980445b