31. 과제를 모델폼으로 변경하기
- ForeignKey는
django.forms.ModelChoiceField
로 표현 - ManyToManyField는
django.forms.ModelMultipleChoiceField
로 표현 - 모델 필드가
blank = True
면, 폼 필드에서required = False
로 설정된다. - 필드의 label은
verbose_name
으로 설정된다.
The save() method
- 폼에 바인딩 된 데이터로 부터 데이터베이스 객체를 만들고 저장한다.
- ModelForm의 subclass는 모델의 인스턴스를
instance
키워드 인자로 받을 수 있다.instance
가 있으면, save()는 인스턴스를 updateinstance
가 없으면, save()는 인스턴스 create
# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)
# Create, but don't save the new author instance.
>>> new_author = f.save(commit=False)
# Modify the author in some way.
>>> new_author.some_field = 'some_value'
# 객체 생성
# Save the new instance.
>>> new_author.save()
# Now, save the many-to-many data for the form.
>>> f.save_m2m()
# Create a form instance with POST data.
>>> a = Author()
# instance는 기존데이터, request.POST는 새로운 데이터
>>> f = AuthorForm(request.POST, instance=a)
# Create and save the new author instance. There's no need to do anything else.
>>> new_author = f.save()
# Post.objetcts.create()
# p = Post()
# p.save()
# 위의 두 가지 방법과 비슷한 개념
# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)
# 객체가 만들어져서 메모리상에 있는 상태
# Create, but don't save the new author instance.
>>> new_author = f.save(commit=False)
# Modify the author in some way.
>>> new_author.some_field = 'some_value'
# Save the new instance.
>>> new_author.save()
# Now, save the many-to-many data for the form.
>>> f.save_m2m()
Model fromsets은 잘 안쓴다. formsets을 쓸 정도가 되면 fontend에서 처리한다.
32. signup 폼도 signup 모델 폼으로 변경
youtube 프로젝트
프로젝트 설정
$ mkdir youtube
$ cd youtube
$ pyenv virtualenv 3.4.3 youtube
$ pyenv local youtube
$ pip install django
$ pip install --upgrade google-api-python-client
$ pip freeze > requirements.txt
$ django-admin startproject youtube
$ mv youtube django_app
$ cp ~/django_girls_class/.gitignore .
$ tree
.
├── django_app
│ ├── manage.py
│ └── youtube
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── requirements.txt
$ mkdir .conf
$ vi .gitignore
# Config folders 추가
.conf/
youtube api key 생성 및 관리
아래의 페이지에서 프로젝트를 만들어 키를 발급받는다.
https://console.developers.google.com/iam-admin/projects
발급받은 API 키는 잘 보관해야 한다. 생성한 .conf
폴더 안에 settigs_local.json
파일 생성
{
"youtube": {
"API_KEY": "your_key"
}
}
# youtube/settings.py
ROOT_DIR = os.path.dirname(BASE_DIR)
CONF_DIR = os.path.join(ROOT_DIR, '.conf')
content = open(os.path.join(CONF_DIR, 'settings_local.json')).read()
config = json.loads(content)
print(content)
print(type(content))
print(config)
print(type(config))
$ ./manage.py runserver
{
"youtube": {
"API_KEY": "your_key"
}
}
<class 'str'>
{'youtube': {'API_KEY': 'your_key'}}
<class 'dict'>
{
"youtube": {
"API_KEY": "your_key"
}
}
<class 'str'>
{'youtube': {'API_KEY': 'your_key'}}
<class 'dict'>
관련 링크
Postman
요청 테스트해보기
- https://www.googleapis.com/youtube/v3/search?part=snippet&q=book
기능 구현
1. api 요청하여 title 출력
- .conf 폴더의 settings_local.json을 읽어서
- 해당 내용을 json.loads()를 이용해 str -> dict 형태로 변환
- requests 라이브러리를 이용(
pip install requests
), GET요청으로 테이터를 받아온 후 - 해당 내용을 다시 json.loads()를 이용해 파이썬 객체로 변환
- 이후 내부에 있는 검색결과를 적절히 루프하여 print 해주기
import os
# 현재 파일의 절대 경로
current_file_path = os.path.abspath(__file__)
# 상위로 이동
go_to_parent_path = os.path.dirname(current_file_path)
# 하위로 이동
go_to_child_path_or_files = os.path.join(go_to_parent_path, 'youtube.py')
print(current_file_path)
print(go_to_parent_path)
print(go_to_child_path_or_files)
# 파이썬이 알아서 파일 자동관리, 파일이 열고 쓰지 않는다는걸 알면 닫아준다.
# 그래도 아래와 같이 써주는게 제일 깔끔하다.
with open(os.path.join(CONF_DIR, 'settings_local.json'), 'r') as f:
config_str = f.read()
print(config_str)
# 모르면 다 프린트해보자
# 디버그문은 정성스럽게 작성하자
import json
import os
import requests
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
CONF_DIR = os.path.join(ROOT_DIR, '.conf')
# print('ROOT_DIR \n {}'.format(ROOT_DIR))
# print('CONF_DIR \n {}'.format(CONF_DIR))
content = json.loads(open(os.path.join(CONF_DIR, 'settings_local.json')).read())
# print(content)
payload = {
'part': 'snippet',
'q': 'grizemanmm',
'key': content['youtube']['API_KEY'],
'maxResults': 50,
}
r = requests.get('https://www.googleapis.com/youtube/v3/search', params=payload)
# print(type(r.content))
raw_data = r.json()
# title = raw_data['items'][0]['snippet']['title']
# print(title)
items = raw_data['items']
for index, item in enumerate(items):
title = item['snippet']['title']
print('title: {}'.format(title))
2. 검색 요청 결과를 데이터베이스에 저장하기
-
video app을 생성하고
-
유튜브 영상의 정보를 저장할 수 있는 Model구현, Migrations
-
POST요청을 받으면 요청에서 온 키워드로 유튜브를 검색 후 결과를 DB에 저장하는 View구현 방금 작성한 code/youtube.py파일의 내용을 하나의 함수로 구현 3-1. GET요청시에는 검색 input이 하나 있는 페이지를 단순 render
3-1-1. 해당 페이지에는 form요소가 있어야 함
3-2. POST요청은 GET요청에 있는 form을 통해서 이루어짐
3-2-1. POST요청으로는 keyword 또는 q라는 이름으로 검색키워드 정보를 전달 3-2-2. 전달받아온 키워드를 이용해 유튜브 검색 API실행 3-2-3. 이후 해당 결과를 적절히 순회하며 DB에 저장 3-2-4. 저장되어있는 모든 데이터를 템플릿에 전달
-
위 View를 나타낼 수 있는 Template구현
-
View와 Template연결
published_date_str = item['snippet']['publishedAt']
# pip install python-dateutil
# 자동으로 스트링을 데이트타입으로 변환
published_date = parse(published_date_str)