지난 포스팅에서 Pycharm과 Anaconda Python을 이용하여 기본적인 장고 프로젝트 생성에 대하여 알아보았습니다.
이번 포스팅에는 프로젝트 내에서 장고 어플리케이션 생성에 대해 알아보도록 하겠습니다.
프로젝트 내에서 가장 쉽게 어플리케이션을 생성하는 방법은 아래의 명령어를 터미널에서 수행하면 됩니다 !
$ python manage.py startapp MyApplication
참고로 공식 도큐먼트에서는 다음과 같은 설명이 있습니다.
Django는 앱의 기본 디렉토리 구조를 생성할 수 있는 도구를 제공합니다. 이 때 App은 특정한 기능을 수행하는 웹 어플리케이션을 의미합니다. Project는 특정 웹 사이트를 위한 app들과 각 설정들을 한데 묶어놓은 것입니다. Project는 다수의 app을 포함할 수 있고, app은 다수의 Project에 포함될 수 있습니다.
이를 수행하면 아래와 같이 MyApplication이라는 디렉토리가 생성됩니다. 해당 디렉토리의 구조는 아래와 같습니다.
앞서 이번에 예시로, 어플리케이션에는 MongoDB, Json과 Html을 이용해 유저에 대한 정보를 저장, 응답하는 서버를 간단히 작성해 보도록 하겠습니다.
우선 MongoDB를 사용하기 위해 적당한 위치에 MongoDbManager.py를 생성하여 아래와 같이 데이터 조회 및 생성 기능을 작성해봅시다.
[MyApplication/MongoDbManager.py]
pymongo 라이브러리를 이용하여 MongoDB에 접속하여 데이터를 조회하거나 생성합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import pymongo
class MongoDbManager:
_instance = None
client = pymongo.MongoClient(host='localhost',
port=27017)
database = client['MyApplicationDB']['MyApplicationCollection']
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
def get_users_from_collection(cls, query):
assert cls.database
return cls.database.find(query)
def add_user_on_collection(cls, data):
if type(data) is list:
return cls.database.insert_many(data)
else :
return cls.database.insert_one(data)
|
cs |
이후 Api라는 디렉토리를 하나 생성합니다. 그 후, JsonTest.py와 HtmlTest.py 파일을 생성하고 아래와 같이 작성합니다.
[MyApplication/Api/JsonTest.py]
json라이브러리를 이용하여 데이터를 Json 형태로 응답합니다.
특정 유저의 경우 specific_user 메소드를, 모든 유저에 대해서는 all_users 메소드를 이용합니다.
특정 유저의 경우 get과 post 메소드로 접근한 경우만 허용을 하고, 모든 유저에 대해서는 get 메소드만 접근을 허용하도록 합니다.
request에는 클라이언트의 요청 정보가 담깁니다. username에는 URL의 username에 대한 정보가 담깁니다.
관련 태스크를 수행한 후, HttpResponse를 통해 상태코드와, DB에서 조회한 데이터를 json 형태로 담아 응답합니다.
클라이언트의 요청 정보 중, POST method에서 Body의 내용은 request.POST를 통해 확인할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
from django.http import HttpResponse
import json
from MyApplication.MongoDbManager import MongoDbManager
def specific_user(request, username):
def get():
users = MongoDbManager().get_users_from_collection({'name': username})
response = users[0]
del response['_id']
return HttpResponse(json.dumps(response), status=200)
def post():
try:
age, job = request.POST['age'], request.POST['job']
except:
return HttpResponse(status=400)
user = {
'name': username,
'age': age,
'job' : job
}
result = MongoDbManager().add_user_on_collection(user)
return HttpResponse(status=201) if result else HttpResponse(status=500)
if request.method == 'GET':
return get()
elif request.method == 'POST':
return post()
else:
return HttpResponse(status=405)
def all_users( request):
def get():
users = MongoDbManager().get_users_from_collection({})
response = []
for user in users:
del user['_id']
response.append(user)
return HttpResponse(json.dumps(response), status=200)
if request.method == 'GET':
return get()
else:
return HttpResponse(status=405)
|
cs |
[MyApplication/Api/HtmlTest.py]
loader와 template.render 메소드를 이용하여 웹 문서를 작성한 뒤 응답합니다.
특정 유저의 경우 specific_user 메소드를, 모든 유저에 대해서는 all_users 메소드를 이용합니다.
get 메소드만 접근을 허용하도록 합니다.
request에는 클라이언트의 요청 정보가 담깁니다. username에는 URL의 username에 대한 정보가 담깁니다.
관련 태스크를 수행한 후, HttpResponse를 통해 상태코드와, DB에서 조회한 데이터를 html 문서에 렌더링을 하여 웹 문서 형태로 응답합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
from django.http import HttpResponse
from django.template import loader
from MyApplication.MongoDbManager import MongoDbManager
def specific_user(request, username):
def get():
db_user_data = MongoDbManager().get_users_from_collection({'name': username})
user = db_user_data[0]
del user['_id']
template = loader.get_template('User.html')
return HttpResponse(template.render({'userData':[user]}, request))
if request.method == 'GET':
return get()
else:
return HttpResponse(status=405)
def all_users(request):
def get():
dbUserData = MongoDbManager().get_users_from_collection({})
users = []
for user in dbUserData:
del user['_id']
users.append(user)
template = loader.get_template('User.html')
return HttpResponse(template.render({'userData': users}, request))
if request.method == 'GET':
return get()
else:
return HttpResponse(status=405)
|
cs |
이후 Html파일을 아래와 같이 간단히 작성합니다. Html파일은 templates 디렉토리에 생성합니다.
[templates/User.html]
Jinja2 템플릿 언어를 이용하여 작성하였습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User</title>
</head>
<body>
{% for user in userData %}
<h1>User</h1>
<ul>
<li>Name: {{ user.name }}</li>
<li>Age: {{ user.age }}</li>
<li>Job: {{ user.job }}</li>
</ul>
{% endfor %}
</body>
</html>
|
cs |
그리고 마지막으로 URL설정을 해줘야합니다.
프로젝트의 urls.py에서 아래와 같이 include와 경로를 추가합니다.
[Django/urls.py]
1
2
3
4
5
6
7
|
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('MyApplication.urls'))
]
|
cs |
그리고 MyApplication 디렉토리에 urls.py라는 파일을 생성하여 다음과 같이 작성합니다. 저는 아래와 같은 역할을 할 수 있도록 경로를 설정하였습니다.
"~/api/json/shin": shin이라는 유저의 정보를 json 형태로 요청한다.
"~/api/json": 모든 유저의 정보를 json 형태로 요청한다.
"~/api/html/shin": shin이라는 유저의 정보를 html 웹 문서로 요청한다.
"~/api/html": 모든 유저의 정보를 html 웹 문서로 요청한다.
[MyApplication/urls.py]
1
2
3
4
5
6
7
8
9
10
|
from django.urls import path
from MyApplication.Api import HtmlTest, JsonTest
urlpatterns = [
path('json/', JsonTest.all_users, name='JsonAllUser'),
path('json/<username>', JsonTest.specific_user, name='JsonSpecificUser'),
path('html/', HtmlTest.all_users, name='HtmlAllUser'),
path('html/<username>', HtmlTest.specific_user, name='HtmlSpecificUser')
]
|
cs |
테스트를 위한 준비가 끝났습니다 ! 서버를 실행합니다.
테스트를 위해 Postman 툴을 이용합니다.
기존의 데이터베이스에는 유저에 대한 정보가 없으니 POST를 이용하여 유저의 정보를 먼저 등록해보도록 하겠습니다.
하지만 위를 수행하면 CSRF 쿠키에 대한 정보를 추가하지 않았기때문에, 403 접근불가 에러가 발생합니다. ( 이는 보안을 위해 토큰 값을 이용해 서버에 접근하는 방식입니다 ! 사실 보안은 자세히 알지 못하기에... 궁금하신 분들은 개인적으로 구글링하시면 되겠습니다.)
이를 해결하기 위해 임시적으로 다음과 같이 POST 메소드를 사용하는 부분에 어노테이션을 추가합니다.
1
2
3
4
5
|
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def specific_user(request, username):
...
|
cs |
이후 다시 포스트맨을 통해 값을 전달하면 서버에 값을 전달받고 데이터베이스에 값이 추가됩니다 !
이제 GET으로 테스트를 해봅시다 !
정상적으로 수행함을 확인할 수 있습니다.
모든 사용자에 대한 정보도 조회해봅니다.
HTML 웹 문서로도 확인해봅니다.
모든 유저에 대해서도 확인해봅니다.
사실 Django는 굉장히 잘 되어있습니다. 데이터베이스를 위한 Model과, 사용자에게 응답을 위한 View 등 기본적으로 생성되는 구조에 대해서만 봐도 사용자를 많이 고려했음이 느껴집니다. ( 공식 도큐먼트에서는 views.py를 사용하는 예시가 준비되어 있습니다.)
데이터베이스도 SqlLite가 기본적으로 생성되며, Oracle 등도 지원하며 Model을 이용해 쉽게 관리가 가능합니다. 관련된 내용은 공식 도큐먼트를 참조하시면 될듯합니다.
참고 : https://docs.djangoproject.com/ko/2.1/intro/tutorial03/
'Development > Etc' 카테고리의 다른 글
한국 지도 시각화하기 및 gps 표시 ( D3.js v5를 이용하여) (0) | 2019.02.13 |
---|---|
Python Flask[플라스크] 시작하기 - 1 (0) | 2019.01.20 |
Python Django[장고] 시작하기 - 1 (Pycharm, Anaconda를 이용하여) (0) | 2019.01.18 |
싱글톤 패턴(Singleton Pattern) 간단하게 구현하기 (0) | 2019.01.08 |
서버(Server), 클라이언트(Client) -기초, 브라우저 (2) | 2018.12.26 |