웹 관련 라이브러리를 이용해서 직접 구현 : 프로젝트 구조부터 전부 직접 생성해야 해서 현실성이 떨어지지만 프레임워크의 구성이나 구동 방식을 이해할 때는 도움이 된다.
웹 관련 프레임워크를 이용 : 빠르게 애플리케이션을 생성
Flask : 자유도가 높고 빠르게 애플리케이션을 만들어서 구동시켜 볼 수 있다 하지만, python에 대해 많이 알아야 한다.
Django : 구조를 생성해주고 이 규칙을 따라야 하므로 자유도는 높지 않다 하지만, 기본 설정이 많이 되어 있기 때문에 복잡한 애플리케이션을 개발할 때 Flask 보다 쉽게 만들 수 있다.
root@e1c64a664a16:/# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 18
Server version: 10.10.2-MariaDB-1:10.10.2+maria~ubu2204 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| euijoodb |
| information_schema |
| mariadb |
| mysql |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.001 sec)
MariaDB [(none)]> grant all privileges on euijoodb.* to 'euijoo'@'%';
Query OK, 0 rows affected (0.005 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.002 sec)
MariaDB [(none)]> exit
Bye
root@e1c64a664a16:/# mysql -u euijoo -p;
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 19
Server version: 10.10.2-MariaDB-1:10.10.2+maria~ubu2204 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| euijoodb |
| information_schema |
| mariadb |
+--------------------+
3 rows in set (0.001 sec)
python web server framework
python 외부 라이브러리라서 설치 필요 : pip install django
MTV - Model, Template, View
프로그래밍을 3가지 영역으로 나누어서 수행
Model : Persistency Store 와 동작하는 부분
Template : 서버의 데이터를 화면에 출력하는 부분
View : 사용자의 요청(Request - URL)이 왔을 때 필요한 Business Logic 을 호출하고 그 결과를 넣어서 Template 에게 전송하는 역할 - Controller
Django의 구성요소
Model : 데이터에 대한 정의를 담고 있는 장고의 클래스
URLConf: URL 정의 - urls.py라는 파일에 url과 호출될 함수를 설정
View : 로직을 처리하는 부분 - 다른 곳에서는 Controller라고 표현하며, views.py 파일에 작성
Template : 화면 출력 설정 - 확장자는 html을 사용하고 여기에 Django의 템플릿 엔진을 이용해서 처리한 데이터를 출력
Django의 구조
웹 생성 - mysite 라느 프로젝트를 만들고 그 안에 mydjango 라는 앱을 생성
프로젝트 생성 : django-admin startproject 이름
앱 생성 : python manage.py startapp 이름
실행 : 터미널에서 명령어로 실행
(venv) euijoolee@EUIJOOui-MacBookAir ~/PycharmProjects/mysite pip install django
Collecting django
Downloading Django-4.1.6-py3-none-any.whl (8.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.1/8.1 MB 65.2 MB/s eta 0:00:00
Collecting asgiref<4,>=3.5.2
Downloading asgiref-3.6.0-py3-none-any.whl (23 kB)
Collecting sqlparse>=0.2.2
Downloading sqlparse-0.4.3-py3-none-any.whl (42 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 42.8/42.8 kB 5.0 MB/s eta 0:00:00
Installing collected packages: sqlparse, asgiref, django
Successfully installed asgiref-3.6.0 django-4.1.6 sqlparse-0.4.3
[notice] A new release of pip available: 22.3.1 -> 23.0
[notice] To update, run: pip install --upgrade pip
데이터베이스 제조사에서 제공하는 API를 이용
SQL을 직접 작성해서 데이터베이스 드라이버에게 전달해서 데이터베이스를 사용
데이터 베이스 마다 드라이버가 다르고 연결하는 방법도 달라서 프로그래밍이 쉽지 않음
Framework의 연동 기술을 이용
SQL Mapper
프로그래밍 코드 와 SQL을 분리해서 작성
코드의 가독성이 높아져서 유지 보수가 위의 방법보다는 쉽고 개발자들이 대부분 SQL을 알고 있기 때문에 접근하기가 쉽지만, 효율이 떨어짐
Mabatis 가 대표적인 SQL Mapper 인데 국내에서는 SI업계에서 주로 사용
ORM
객체 지향 언어의 클래스(인스턴스)와 RDBMS(관계형 데이터베이스)의 테이블을 매핑시켜 사용하는 방식
SQL없이 관게형 데이터베이스 사용이 가능
데이터베이스 종류에 상관없이 동일한 인터페이스로 사용 가능 - 데이터베이스 종류를 변경하는 것은 설정의 변경만으로도 된다
공부하기 어렵다는 단점이 있지만 효율이 높기 때문에 솔루션 업체에서 주로 이용
Java 의 JPA, Python의 Django 등이 대표적인 ORM 프레임워크
ALLOWED_HOSTS = []
* 실행할 서버의 IP 설정인데 비워두면 localhost, 127.0.0.1 가 설정되고 혹은 루프백 주소를 기입해도 된다.
* 개발 모드인 경우는 비워두거나
------------------------------
* 프로젝트에 실행할 APP을 등록하는 부분 - Application을 추가한 경우 실행을 위해서 추가
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
------------------------------
* 사용할 데이터 베이스 설정
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
------------------------------
* 시간대 설정
TIME_ZONE = 'Asia/Seoul'
------------------------------
* static 파일의 경로 : css 나 js 또는 이미지 처럼 절대로 변경되지 않는 외부 자원을 static 이라고 한다
STATIC_URL = 'static/'
(venv) ✘ euijoolee@EUIJOOui-MacBookAir ~/PycharmProjects/mysite cd mysite
(venv) euijoolee@EUIJOOui-MacBookAir ~/PycharmProjects/mysite/mysite python manage.py runserver localhost:8000
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
February 02, 2023 - 11:35:16
Django version 4.1.6, using settings 'mysite.settings'
Starting development server at http://localhost:8000/
Django 는 관리자 모드를 탑재
관리자 생성 : python manage.py createsuperuser
URL Mapping
urls.py 파일에 사용할 URL 과 호출될 함수를 연결
이 때 사용되는 함수는 path 함수
path 함수는 2개의 필수 인자 와 2개의 선택 인자를 받음
필수 인자는 route 와 view인데 route는 처리할 URL이고 view는 호출될 함수
kwargs 는 선택인자인데 URL에서 추출된 항목 이외의 데이터를 전달하고자 할 때 사용하는 것으로 python의 dict 타입으로 전달해야 한다
name 은 이름
<메인 앱의 urls.py>
"""
from django.contrib import admin
from django.urls import path
# 실제 함수가 위치할 파일을 Import
from mydjango import views
urlpatterns = [
path('admin/', admin.site.urls),
# 기본 요청이 왔을 때 mydjango의 views.py 파일의 index 함수가 처리
path("",views.index)
]
< 다른 앱의 views.py>
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
# 클라이언트의 요청을 처리하는 함수
# 이 함수의 매개변수는 HttpRequest 타입인데
# 이 타입은 클라이언트의 정보를 가진 클래스
def index(request):
# 클라이언트에게 문자열 응답을 전송
return HttpResponse("Hello Django");
HTML 파일에 서버에서 처리한 데이터를 출력하는 것
Template Engine : 서버가 처리한 데이터를 HTML 사이에 출력하도록 도와주는 라이브러리이고 Django는 내장하고 있음 하지만, 최근에는 이 방식의 출력을 권장하지는 않음
mydjango/viwes.py를 수정해서 html 을 출력하도록 변경
def index(request):
# 클라이언트에게 문자열 응답을 전송
#return HttpResponse("Hello Django");
msg = 'use first Template Engine'
# template 디렉토리에 있는 index.html 파일로 출력하는데
# 데이터를 message 라는 이름으로 전달
# request 와 함께 전달해서 화면을 만드는 것을 forwarding 이라고 한다
return render(request, 'index.html',{"message":msg})
{% if 조건 %}
처리할 내용
{% else %}
처리할 내용
{% end if%}
def index(request):
# 클라이언트에게 문자열 응답을 전송
#return HttpResponse("Hello Django");
msg = 'use first Template Engine'
# template 디렉토리에 있는 index.html 파일로 출력하는데
# 데이터를 message 라는 이름으로 전달
# request 와 함께 전달해서 화면을 만드는 것을 forwarding 이라고 한다
success = False
name = "lee"
return render(request, 'index.html',{"message": msg,"success":success,"name":name})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>메인</title>
</head>
<body>
{{message}}<br />
{{name}}<br />
{{success}}<br />
{% if success == True %}
성공<br/>
{% else %}
실패<br/>
{% endif %}
{% if name is lee %}
로그인<br/>
{% else %}
{{name}} 님 안녕하세요<br/>
{% endif %}
</body>
</html>
{% for 임시변수 in 리스트 %}
처리할 내용
{% endfor %}
def index(request):
# 클라이언트에게 문자열 응답을 전송
#return HttpResponse("Hello Django");
msg = 'use first Template Engine'
# template 디렉토리에 있는 index.html 파일로 출력하는데
# 데이터를 message 라는 이름으로 전달
# request 와 함께 전달해서 화면을 만드는 것을 forwarding 이라고 한다
success = False
name = "lee"
ar = ["Developer","Operator","DevOps","MLOps"]
return render(request, 'index.html',{"message": msg,"success":success,"name":name,"ar":ar})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>메인</title>
</head>
<body>
{{message}}<br />
{{name}}<br />
{{success}}<br />
{% if success == True %}
성공<br/>
{% else %}
실패<br/>
{% endif %}
{% if name is lee %}
로그인<br/>
{% else %}
{{name}} 님 안녕하세요<br/>
{% endif %}
<ol>
{% for job in ar %}
<li>{{job}}</li>
{% endfor %}
</ol>
</body>
</html>
Django 에서 데이터베이스 연동하는 부분을 model이 처리
ORM : 객체 지향 언어의 객체 와 관계형 데이터베이스(RDBMS)의 하나의 행을 1:1로 매칭시켜서 객체 지향 문법으로 데이터베이스를 사용하는 프레임 워크
models.py 파일에 클래스 형태로 데이터베이스 테이블과 연동할 클래스를 선언
연동할 테이블이 없으면 테이블을 자동 생성하고 Primary Key가 없으면 id를 자동으로 생성
클래스 안에 static 필드를 선언하고 자료형 과 제약조건을 설정
데이터 베이스 연결은 데이터베이스에 해당하는 라이브러리를 설치하고 settings.py 파일의 DATABASES 라는 변수에 접속 정보를 기재하면 됨
접속 기재 방법은 https://docs.djangoproject.com/en/4.1/ref/settings/#databases
설정한 내용을 반영
python manage.py makemigrations
python manage.py migrate
만들어지는 테이블 이름은 앱이름_ModelClass 이름
$ brew install mysql-client
$ echo 'export PATH="/usr/local/opt/mysql-client/bin:$PATH"' >> ~/.bash_profile
$ export PATH="/usr/local/opt/mysql-client/bin:$PATH"
$ pip install mysql-client
from django.db import models
class Item(models.Model):
itemid = models.CharField(max_length=50, primary_key=True)
itemname = models.CharField(max_length=50)
price = models.IntegerField()
description = models.CharField(max_length=50)
pictureurl = models.CharField(max_length=50)
python manage.py makemigrations
python manage.py migrate
insert into mydjango_item values(1, 'Lemon', 500, 'Vitamin-A', 'lemon.jpg');
insert into mydjango_item values(2, 'Orange', 1500, 'Vitamin-B', 'orange.jpg');
insert into mydjango_item values(3, 'Kiwi', 2000, 'Vitamin-C', 'kiwi.jpg');
insert into mydjango_item values(4, 'Grape', 1000, 'Vitamin-D', 'grape.jpg');
insert into mydjango_item values(5, 'Strawberry', 2000, 'Vitamin-E', 'strawberry.jpg');
insert into mydjango_item values(6, 'Mandarin', 300, 'Vitamin-F', 'mandarin.jpg');
commit;
select * from mydjango_item;
from django.shortcuts import render
from mydjango.models import Item
# Create your views here.
from django.http import HttpResponse
def index(request):
print(Item) # 확인용
data = Item.objects.all()
print(data) # 확인용
return render(request, 'index.html', {'data':data});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>목록 보기</title>
</head>
<body>
<h2>상품 목록 화면</h2>
<table border="1">
<thead>
<tr>
<th>상품ID</th>
<th>상품이름</th>
<th>가격</th>
</tr>
</thead>
<tbody>
{% for item in data %}
<tr>
<td>{{item.itemid}}</td>
<td>{{item.itemname}}</td>
<td>{{item.price}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
목록보기에서 제목 등의 부분에 링크를 설정해서 링크를 누르면 데이터를 자세히 출력하는 형태로 많이 구현함
제목을 클릭할 때 하나의 데이터를 찾을 수 있도록 기본키 값을 전달해야 한다.
기본키를 가지고 데이터를 검색해서 출력한다.
예전에는 데이터를 넘길 때 파라미터 방식을 많이 사용했는데 최근에는 URL에 포함시키는 형태를 많이 사용한다.
index.html 파일의 제목 출력 부분을 변경
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>목록 보기</title>
</head>
<body>
<h2>상품 목록 화면</h2>
<table border="1">
<thead>
<tr>
<th>상품ID</th>
<th>상품이름</th>
<th>가격</th>
</tr>
</thead>
<tbody>
{% for item in data %}
<tr>
<td>{{item.itemid}}</td>
<td><a href="/detail/{{item.itemid}}">{{item.itemname}}</td>
<td>{{item.price}}</td>
</tr>
{% endfor %}
</tbody>v
</table>
</body>
</html>
"""
from django.contrib import admin
from django.urls import path
# 실제 함수가 위치할 파일을 Import
from mydjango import views
urlpatterns = [
path('admin/', admin.site.urls),
# 기본 요청이 왔을 때 mydjango의 views.py 파일의 index 함수가 처리
path("",views.index),
# detail/숫자 요청이 오면 views.py 파일의 detail 함수가 처리
path('detail/<int:itemid>',views.detail)
]
from django.shortcuts import render
from mydjango.models import Item
# Create your views here.
from django.http import HttpResponse
# 클라이언트의 요청을 처리하는 함수
# 이 함수의 매개변수는 HttpRequest 타입인데
# 이 타입은 클라이언트의 정보를 가진 클래스
def index(request):
# 클라이언트에게 문자열 응답을 전송
#return HttpResponse("Hello Django");
#msg = 'use first Template Engine'
# template 디렉토리에 있는 index.html 파일로 출력하는데
# 데이터를 message 라는 이름으로 전달
# request 와 함께 전달해서 화면을 만드는 것을 forwarding 이라고 한다
success = False
name = "lee"
data = Item.objects.all()
print(data)
ar = ["Developer","Operator","DevOps","MLOps"]
return render(request, 'index.html',{"data":data})
def detail(request,itemid):
# itemid를 가진 데이터 찾아옴
item = Item.objects.get(itemid=itemid)
print(item)
return render(request,'detail.html',{'item':item})
imports os # 임포트 해주고
STATIC_URL = 'static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, '../static')]
# 수정
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>상품 상세보기</title>
</head>
<body>
<h2>상품 상세 보기</h2>
<table border="1">
<tr>
<td>상품 아이디</td>
<td>{{item.itemid}}</td>
</tr>
<tr>
<td>상품 이름</td>
<td>{{item.itemname}}</td>
</tr>
<tr>
<td>가격</td>
<td>{{item.price}}</td>
</tr>
<tr>
<td colspan="2">
<img src="{% get_static_prefix %}img/{{item.pictureurl}}"/>
</td>
</tr>
</table>
</body>
</html>