django 코드 작성
django 코드 작성은 이전 프로젝트 구조에 맞춰서 개발한다.
☞ django 프로젝트 구조는 이전 글 참고
django cycle, 프로젝트 구조 및 language, timezone 변경하기 #3
django cycledjango는 아래와 같은 사이클로 작동되며, 소스 코드도 아래 사이클에 맞춰 개발한다.WSGI (Web Server Gateway Interface)파이썬 스크립트(웹 어플리케이션)가 웹 서버와 통신하기 위한 인터페이
yuneenelife.tistory.com
작성할 코드 흐름
- urls.py
- path는 /api/pubd/
- 상세 URL들은 pubdapp 앱 내 urls.py 생성하여 관리한다.
- views.py
- nanet_search() 함수 생성한다.
- nanet_post() 함수 생성한다.
- settings.py
- git에 공유되지 않아야 할 주요 키 값들 저장
- api.py
- api 호출되는 함수 모음 파일 신규 생성한다.
- axios로 연계되는 로직은 모두 이 파일에 작성한다.
- nanet_api() 함수 생성한다.
- models.py
- request와 response를 저장하기 위한 기초 작업
- nanet 클래스 생성한다.
urls.py
- urls.py
#urls.py 파일
from django.contrib import admin
from django.urls import path, include
#url 패턴 모음
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('rest_framework.urls')),
path('api/pubd/', include('pubdapp.urls')), #공공데이터 포탈 API URL 모음
]
- pubdapp/urls.py
from django.urls import path
from .views import nanet_search
#url 패턴 모음
urlpatterns = [
path('nanet_main/', nanet_search), #공공데이터 조회 URL 생성
]
views.py
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny
from .api import nanet_api
from .models import Nanet
# Create your views here.
@api_view(['GET'])
@permission_classes([AllowAny])
def nanet_search(request):
param = []
test = []
param.append(request.GET.get('search'))
param.append(request.GET.get('pageno'))
param.append(request.GET.get('displaylines'))
#파라미터가 있으면 로그 생성
if param[0] is not None:
create_nanet_log(param)
#없으면 테스트 로그 생성
else:
test.append('자체 테스트중')
test.append(1)
test.append(10)
create_nanet_log(test)
#api 함수 호출
res = nanet_api(param)
#응답
return Response(res)
#로그 생성 함수
def create_nanet_log(param):
nanet_save = Nanet(search=param[0], pageno = param[1], displaylines=param[2])
nanet_save.save()
환경변수 settings.py 에 추가
URL과 git으로 공유되지 않아야 할 API KEY 값 들은 별도 환경변수에 저장하여 활용한다.
- INSTALLED_APPS에 pubdapp 추가
- EXTERNAL_URLS에 공공데이터 포털 API 입력
- EXTERNAL_KEYS에 공공데이터 포털 KEY 입력
#URL과 git으로 공유되지 않아야 할 API KEY 값 들은 별도 환경변수에 저장하여 활용한다.
#INSTALLED_APPS에 pubdapp 추가
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'pubdapp',
]
#EXTERNAL_URLS에 공공데이터 포털 API 입력
EXTERNAL_URLS = {
'NANET_API': 'http://apis.data.go.kr/9720000/searchservice/basic',
}
#EXTERNAL_KEYS에 공공데이터 포털 KEY 입력
EXTERNAL_KEYS = {
'NANET_KEY': '공공데이터 포털에서 받은 API KEY 기입',
}
api.py
- api 주요 정보는 settings 모듈을 통해 환경변수에서 가져온다.
from django.conf import settings
from urllib.parse import urlencode, unquote, quote_plus
import requests, xmltodict
def nanet_api(param):
#api 주요 정보는 settings 모듈을 통해 환경변수에서 가져온다.
url = settings.EXTERNAL_URLS['NANET_API']
serviceKey = settings.EXTERNAL_KEYS['NANET_KEY']
serviceKeyDecoded = unquote(serviceKey, 'UTF-8')
#파라미터 validation check
P = validation_api('nanet', param)
if (P[0] == 'noapi'):
return False
#print("param :", P)
#api 호출할 파라미터 조합
queryParams = '?' + urlencode({ quote_plus('ServiceKey') : serviceKeyDecoded
, quote_plus('pageno') : P[1]
, quote_plus('displaylines') : P[2]
, quote_plus('search') : P[0] })
#api 호출
res = requests.get(url + queryParams)
xml = res.text
rsp = xmltodict.parse(xml)
#print("rsp :", rsp)
return rsp
#파라미터 validation 체크 함수
def validation_api(apiNm, param):
rtn = []
try:
#api명이 정상일떄
if (apiNm == 'nanet'):
#파라미터 0번째가 없는 것은 테스트를 위해 초기값 설정한다.
if param[0] is None:
param[0] = '자료명,삼국지'
param[1] = 1
param[2] = 10
else:
param[0] = str(param[0])
#api명이 비정상일때는 noapi 로 리턴
else:
return rtn.append("noapi")
return param
#예외처리
except Exception as ex:
print("ERROR validation_api()", ex)
request 모듈 설치
- 가상환경에 들어가서 request 모듈 인스톨한다.
- pip install requests
#request 모듈 인스톨 명령어는 pip install requests
#Successfully installed 나오면 성공
(pubd_api) pubdapi % ls
db.sqlite3 manage.py pubdapi pubdapp
(pubd_api) pubdapi % pip install requests
Collecting requests
Using cached requests-2.32.3-py3-none-any.whl.metadata (4.6 kB)
Collecting charset-normalizer<4,>=2 (from requests)
Using cached charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl.metadata (33 kB)
Collecting idna<4,>=2.5 (from requests)
Using cached idna-3.7-py3-none-any.whl.metadata (9.9 kB)
Collecting urllib3<3,>=1.21.1 (from requests)
Using cached urllib3-2.2.2-py3-none-any.whl.metadata (6.4 kB)
Collecting certifi>=2017.4.17 (from requests)
Downloading certifi-2024.7.4-py3-none-any.whl.metadata (2.2 kB)
Using cached requests-2.32.3-py3-none-any.whl (64 kB)
Downloading certifi-2024.7.4-py3-none-any.whl (162 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 163.0/163.0 kB 2.4 MB/s eta 0:00:00
Using cached charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl (119 kB)
Using cached idna-3.7-py3-none-any.whl (66 kB)
Using cached urllib3-2.2.2-py3-none-any.whl (121 kB)
Installing collected packages: urllib3, idna, charset-normalizer, certifi, requests
Successfully installed certifi-2024.7.4 charset-normalizer-3.3.2 idna-3.7 requests-2.32.3 urllib3-2.2.2
(pubd_api) pubdapi %
xmltodict 모듈 설치
- XML 데이터를 파싱하고 Dict 형식으로 변환시키기 위해 필요하다.
- 가상환경에 들어가서 xmltodict 모듈 인스톨한다.
- pip3 install xmltodict
#XML 데이터를 파싱하고 Dict 형식으로 변환시키기 위해 필요하다.
#가상환경에 들어가서 xmltodict 모듈 인스톨한다.
#명령어는 pip3 install xmltodict
(pubd_api) pubdapi % pip3 install xmltodict
Collecting xmltodict
Using cached xmltodict-0.13.0-py2.py3-none-any.whl.metadata (7.7 kB)
Using cached xmltodict-0.13.0-py2.py3-none-any.whl (10.0 kB)
Installing collected packages: xmltodict
Successfully installed xmltodict-0.13.0
(pubd_api) pubdapi %
models.py
- 요청한 파라미터를 저장하기 위한 모델 작성
#요청한 파라미터를 저장하기 위한 모델 작성
from django.db import models
# Create your models here.
class Nanet(models.Model):
#페이지 번호
pageno = models.DecimalField(max_digits=4, decimal_places=0)
#페이지 하나에 나오는 라인 수
displaylines = models.DecimalField(max_digits=4, decimal_places=0)
#검색어
search = models.CharField(max_length=500)
#생성날짜
create_date = models.DateTimeField(auto_now_add=True)
- 모델을 데이터베이스에 반영
- makemigrations 실행
- python3 manage.py makemigrations
- 모델을 변경한 것에 기반한 새로운 마이그레이션을 만들 때 사용
#모델을 데이터베이스에 반영한다.
#명령어는 python3 manage.py makemigrations
#모델을 변경한 것에 기반한 새로운 마이그레이션을 만들 때 사용한다.
(pubd_api) pubdapi % python3 manage.py makemigrations
Migrations for 'pubdapp':
pubdapp/migrations/0001_initial.py
- Create model Nanet
(pubd_api) pubdapi %
- migrate 실행
- 마이그레이션을 반영하거나 반영하지 않기 위해 사용
- python3 manage.py migrate
#migrate 실행
#마이그레이션을 반영하거나 반영하지 않기 위해 사용
#명령어는 python3 manage.py migrate
(pubd_api) pubdapi % python3 manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, pubdapp, sessions
Running migrations:
Applying pubdapp.0001_initial... OK
(pubd_api) pubdapi %
데이터 확인을 위한 admin 관리자 페이지 생성
- 관리자 설정하여 관리자 페이지에서 확인한다.
# 관리자 계정 생성한다.
python manage.py createsuperuser
# 개발 서버 실행한다.
python manage.py runserver
admin.py
from django.contrib import admin
# Register your models here.
from .models import Nanet
# myapp/admin.py
admin.site.register(Nanet)
어드민 페이지
- http://localhost:8000/admin/pubdapp/nanet/
국회도서관 자료검색 API 조회결과
- http://localhost:8000/api/pubd/nanet_main/
마무리
이로써 django 에서 국회도서관 자료검색 호출하고 응답까지 완성되었다.
다음은 해당 API 요청/응답 문서를 관리하는 swagger를 적용시켜 본다.
☞ python, django 설치는 이전 글 참고
API Server django python Framework 설치 #1
python framework 인 django를 이용해서 API Server를 구축한다.API는 공공데이터 포털에서 제공하는 국회 도서관 자료검색 서비스를 이용한다. 먼저 작업을 시작하기에 앞서 작업을 진행할 폴더를 생성
yuneenelife.tistory.com
'국회도서관 자료검색 서비스' 카테고리의 다른 글
django Test 코드 작성하여 코드 안정성 높이기 #11 (0) | 2024.08.12 |
---|---|
django rest framework swagger drf_yasg 설정 #10 (0) | 2024.08.09 |
django APP들을 위한 마이그레이션(migrate) 작업#8 (0) | 2024.08.07 |
pylint 로 python 가상환경 venv 코드와 vs code 와 연결시키기 #7 (0) | 2024.08.06 |
django cors 크로스 도메인 오류 해결 #6 (0) | 2024.08.05 |