Django
파이썬으로 만들어진 무료 오픈소스 웹 애플리케이션 프레임워크(web application framework). MVC 패턴을 따르고 있다.
프레임워크는 포트(port)에 도착한 요청(request)를 확인해주는 웹서버가 웹페이지와 함께 답장(response)을 할 때에 그 특정 콘텐츠 내용을 만들 수 있는 역할을 한다. 장고는 웹서버의 요청을 받으면 urls에서 경로를 대조한 후 일치하는 패턴이 있다면 view에게 넘겨준다.
[ Django 설치 ]
Django 설치 및 createsuperuser
1. pycharm 프로젝트 생성
1) new project > 위치 뒤쪽에 앱 이름 설정( /home/kosmo_03/PycharmProjects/myapps) > conda로 바꾼 뒤 3.7버전으로 바꾸기
2) 파일 > : settings > project : myapps > interpreter 가 3.7인지 확인
3) myapps 곳이 우리의 작업장이다. 터미널에서 작업할 경우 필히 옮겨가서 작업해줄 것.
2. 디장고(Django) 설치
1) myapp 에 django를 설치
pip install django
2) 설치된 장고를 통해서 프로젝트와 앱을 생성해준다.
프로젝트를 시작하고 config 파일을 생성한다. 마지막 온점도 꼭 써야한다.
django-admin startproject config .
3) config > setting.py에서 ip 주소를 써준다.
ALLOWED_HOSTS = ['아이피 주소 쓰기']
## ip 주소는 터미널에서 ip addr을 하면 나온다.
3. admin에서 관리되는 앱 만들기
1) 파이썬의 데이터 베이스인 sqlite3 과 연결시켜준다.
python manage.py migrate
2) 슈퍼유저 아이디와 이메일을 입력하고 비밀번호를 두 번 입력한다.
-> 아이디 admin / 비밀번호 admin으로 설정
3) address라는 앱을 등록 및 환경설정하기(디장고의 MVT 구조를 이해)
python manage.py startapp [생성할 앱 이름]
4. sqlitestudio 리눅스 버전 파일 설치
https://github.com/pawelsalawa/sqlitestudio/releases
1) sqlitestudio-3.2.1.tar.xz > 파일저장 > 압축풀기 > sqlitestudio 파일 열기 > 설치 언어 그냥 영어로 해두기
2) Datebase > add a database > 파일 추가 > pycharm project > db.sqlite3 클릭
3) pycharm으로 돌아가 데이터베이스가 sqlite3로 바뀌어 있는 거 확인
디장고로 하면 스프링과 환경이 똑같기 때문에 복습이 가능하다.
DAO로 만드는 것까지 똑같기 때문.
5. setting.py 를 설정
아까 ip 설정한 것 외에 다른 세팅도 필요하다.
1) 언어설정
쭉 아래가면 Language_code= 'ko' Time zone = 'Asia/Seoul' 설정
Language_code= 'ko'
Time zone = 'Asia/Seoul'
2) INSTALLED_APPS = 아래에 자신이 만든 앱을 추가
INSTALLED_APPS = [ ........
'address',
]
[ 주소록 만들기 ]
Address App 개발 (폼처리,CSRF,redirect등)
1. address의 디렉토리로 templates 만들기
address > templates > address > 거기 안에 index.html 만들기
2. views.py 들어가서 파일 설정해주기
address/view파일에 index 파일 불러오기(request)
from django.shortcuts import render
# Create your views here.
def home(requsest):
return render(requsest, "address/index.html")
3. address에 urls.py 파일 만들기
address를 통제하는 Controller(=urls)를 만들자.
address/urls.py 생성 후 기본적인 index 페이지 경로 설정
from django.urls import path
from address import views
urlpatterns=[
path("",views.home)
]
4. 사용자의 요청을 받는 Controller에 adress 경로를 추가
- config> urls(메인 컨트롤러)에 address/urls의 경로 권한 포함시켜주기
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('address/',include('address.urls')),
]
5. 서버를 실행해서 확인
python manage.py runserver '0.0.0.0:9000'
단, 주소 뒤에 /address 를 붙여주도록 한다.
cf ) 혹시나 아까 했던 ip가 부딪혀서 안될경우 settings.py의 ip에 '0.0.0.0'을 추가해서 파이어폭스 내부의 ip를 사용하도록 한다.
[ Django 구조 ]
spring | Django | 실제파일 |
Controller | Controller | urls.py |
Model | Model | views.py |
View | Templates | templates 폴더 속 전부 |
DAO | dao | models.py |
[ 차이점 ] | ||
MVC 구조 | MVT 구조 | * T는 view(=Templates)를 의미 |
- 사용자 요청이 들어오면 Controller의 Handler Mapping(request mapping)이 url과 메소드를 분석한다.
- 모든 요청을 Controller가 받아서 Model에서 수행하고 그 결과를 View로 보내준다.(제어) : 중앙집중식
- 뷰로 전달을 할 때 전달 방식은 두가지가 있다. 1. forward 2. redirect
- Django에서 Controller는 config에 있는 urls 가 그 역할을 한다. 사용자의 요청은 config로 오고 그걸 Model로 보낸다.
- MVC 기반으로 하는 것. Django는 spring에 비하면 코드가 현저히 적다.
- Django도 클래스 개념이기 때문에 객체 지향이다. 단점이 있다면 인터프리터(interpreter)가 전부. 파이썬의 경우 모든걸 다 올려야 하기 때문에 모든 코드가 다 보여진다. 자바의 경우 보여지고 싶은것만 보여질 수 있다.(=뷰)
- ORM : 마이바티스와 같은 애들은 쿼리를 직접 쓰는거. 1. docker? sqlite로 맵핑? 또는 2. jdbc로 연동하거나.
- DAO는 sql문을 직접 썼다 -> MyBatis
- 이 객체를 쓰면 select가 된다, 뭐가 된다. -> Hibernate. 굉장히 직관적 ( 참고 )
6. address > models.py 설정
java는 class 단위로 정의 한 후 생성해서 사용한다. Dao에 해당된다.
이제 모델 DAO를 만들러 가자.
* 이제부터 등록하는 건 db.sqlite3에 저장되는 것. *
1) 클래스 선언
자바의 상속처럼 파이썬에서 Django에서 제공해주는 기본 models에 있는 model을 상속받겠다는 뜻.
class Address(models.Model):
+ 클래스 안에 객체가 들어오면 상속이다.
2) 컬럼 만들기
sql에서 create 하듯이 정의해준다. 이렇게 정의한 후 명령어만 주면 알아서 만들어진다.
#idx(필드명,컬럼명) = 자료형(속성)
idx = models.AutoField(primary_key=True)
#길이제한, 빈값을 허용, nulll값 허용
name = models.CharField(max_length=50,blank=True,null=True)
tel = models.CharField(max_length=50,blank=True,null=True)
email = models.CharField(max_length=50, blank=True, null=True)
address = models.CharField(max_length=500, blank=True, null=True)
7. admin.py 열기
admin.py에서 Address란 클래스를 정의 -> 테이블 구조, DTO의 역할
AddressAdmin 클래스는 디장고의 관리자에 추가하기 위한 기능
class AddressAdmin(admin.ModelAdmin):
list_display = ('name', 'tel', 'email', 'address')
#디장고의 관리자모드에서 새롭게 관리될 Address, AddressAdmin을 등록한다.(ctrl+space2번)
admin.site.register(Address,AddressAdmin)
+ 각각 Address와 AddressAdmin에 마우스 커서를 두고 ctrl + space를 두번 누르면 알맞은 클래스를 import 할 수 있다.
8. local 창 입력 : table 생성
1) 마이그레이션 파일 생성
python manage.py makemigrations
2) 마이그레이션 적용
python manage.py migrate
그러면 address가 생긴다.
3) 그러면 sqlite에 address_address가 자동으로 생긴다.
DB 연동이 된 것.
4) 주소창에서 admin으로 연결하면 이와같은 창이 나온다.
[ 마이그레이션(migration) ]
마이그레이션이란, 한 운영환경으로부터 다른 운영환경으로 옮기는 작업을 뜻한다.
(예, 윈도우 --> 리눅스)
하드웨어, 소프트웨어, 네트워크 등 넓은 범위에서 마이그레이션의 개념이 사용되고 있다.
CRUD(Create, Read, Update, Delete)를 잘 수행하려면,
데이터 베이스 테이블 스키마가 잘 정의되어 있어야한다.
데이터베이스에서 데이터 마이그레이션이란,
데이터 베이스 스키마의 버전을 관리하기 위한 하나의 방법(데이터 전환)이다.
개발 시스템에는 데이터베이스 스키마가 변경되었지만,
운영시스템의 데이터베이스 스키마가 변경되지 않았을 경우 마이그레이션을 수행한다.
작게는 프로젝트 상 테이블 생성 및 변경 작업부터,
하나의 애플리케이션 또는 시스템을 옮기는 것까지 마이그레이션이다.
요구사항에 따라 애플리케이션과 스키마가 바뀌었고,
개발 과정에는 적용됐지만 운영환경에는 적용되지 않아서 전환 시 애를 먹는 경우가 있다.
데이터베이스 마이그레이션은 이러한 문제를 해결한다.
데이터베이스 마이그레이션은,
개별 SQL 파일을 MySQL 콘솔 등에서 직접 실행하지 않고,
프레임워크의 특정명령어를 통해 실행하고 이 결과를 별도의 테이블에 버전 관리를 하는 기법이다.
출처 : life-with-coding.tistory.com/68
9. django 사이트에서 확인하기
1) 잘 됐는지 보기 위해 admin으로 로그인한다.(admin/admin)
2) 데이터에 주소를 추가해보자.
10. 디장고(Django) 구동 - 폼 만들기
1) 뷰 만들기(addressList.html 생성)
주소록을 가져오기 위한 페이지를 만든다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>addressList.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<div><h3> Address List </h3>
<!--<p> 여기는 주소록 리스트 : {{msg}}</p>-->
<p> 여기는 주소록 리스트 : {{address_count}}</p>
<!--<p> {{items}}</p>-->
<table>
<thead>
<tr>
<th>번호</th>
<th>이름</th>
<th>전화번호</th>
<th>이메일</th>
<th>주소</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="5">
<input type="button" value="등록" onclick="location='write'">
</th>
</tr>
</tfoot>
<tbody>
<!--jstl 사용-->
{% for e in items %}
<tr>
<td>{{e.idx}}</td>
<td>{{e.name}}</td>
<td>{{e.tel}}</td>
<td>{{e.email}}</td>
<td>{{e.address}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
아까 models.py에서 선언한 변수들을 가져온다. jstl을 사용해서 표 안에 값을 넣는다. ( jstl 참고 )
2) index.html에 연결하자.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>나의 첫번째 페이지 !</h2>
<h3>주소록 데모 만들기</h3>
<ul>
<li><a href="list">Address list</a></li>
</ul>
</body>
</html>
3) 이제 모델을 만들자(views.py)
views.py에서 addressList.html의 요청 받아오고, views.py 파일에 list 정의하기
from django.shortcuts import render
# Create your views here.
from address.models import Address
def home(request):
return render(request, "address/index.html")
def list(request):
# ----------------------------------------------------
# select * from address_address
#select count(*) from address_address
#sql문을 사용할 수 있지만 보통은 함수로 호출해서 사용하는 것이 일반적
# - Addressw.objects 레코드 주소
# - order_by('') : 오름차순
# - order_by('-') : 내림차순
# ----------------------------------------------------
items = Address.objects.order_by('name')
#group 함수
address_count = Address.objects.all().count()
#이제 이 값을 url에 넘겨줘야지.
return render(request, "address/addressList.html", {'items': items,
'address_count':address_count})
4) 컨트롤러 설정
address/urls.py 에 "list" 경로 추가 (주소 목록)
from django.urls import path
from address import views
urlpatterns=[
path("",views.home),
path("list",views.list),
]
5) 실행
-> 터미널 실행
python manage.py runserver '0.0.0.0:9000'
# 등록버튼을 누르면 write로 가게 addressList.html에서 onclick을 걸어주었다.
6) addressWrite.html 생성
주소를 입력할 write 창을 만든다. input 태그를 이용해서 입력창을 만들고 아까 onclick으로 걸어주었으니 submit으로 DB에 보내준다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>addressList.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<h1> Address Write 예제 </h1>
<form method="post" action="insert">
<table>
<tr><td>이름</td><td><input type="text" name="name"></td></tr>
<tr><td>전화번호</td><td><input type="text" name="tel"></td></tr>
<tr><td>이메일</td><td><input type="email" name="email"></td></tr>
<tr><td>주소</td><td><input type="text" name="address"></td></tr>
<tr><input type="submit"></tr>
</table>
</form>
</body>
</html>
7) views.py에 addressWrite 등록하기
뷰에 addressWirte.html이 request 될 수 있도록 write를 정의해준다.
write 입력창에 적은 form 파라미터가 DB에 제대로 입력되기 위해 Address에 POST로 보내준다.
레코드 추가 후 redirect 해준다.(수입을 위해 ctrl +space x2)
def write(request):
return render(request,"address/addressWrite.html")
#form 파라미터 처리
def insert(request):
#print("name :", request.POST['name'])
#데이터 베이스에 입력 처리 (idx 는 Oracle의 순번과 동일)
addr = Address(name=request.POST['name'],
tel = request.POST['tel'],
email = request.POST['email'],
address = request.POST['addr됨ess'],
)
addr.save() #레코드 추가
# redirect 때는 /로 절대경로 설정해주어야함.
return redirect("/address/list")
##### redirect의 수입을 위해 ctrl+space 하면 자동 수입됨 #####
8) address/urls.py에 path 지정하기
write 입력창과 DB로 보내는 insert 창 보내기
path("write",views.write),
path("insert",views.insert),
9) 데이터 입력 후 전송하기
[에러] csrf 검증에 실패했습니다.
Django는 CSRF(cross site Request Forgery) 사이트 위조 방지 설정이 기본적으로 설정 체크하게 되어있다.
ex) 해커들이 사이트를 동일하게 꾸며서 정보 빼내는 것 등을 방지하기 위해 FORM을 전송할 때 랜덤으로 생긴 검증을 맞춰야 전송된다.
{% csrf_token%}
따라서 이같은 코드를 항상 추가해주어야 한다.(addressWrite.html에 추가)
10) 결과
11) 상세페이지 만들기(detail.html)
detail.html을 만든다.
수정, 삭제 기능과 전체 addressList와 연결시키려고 한다.
12) addressList.html에 detail 링크 연결하기
이름 누르면 detail(그중에 idx가 해당하는 것)으로 이동하게 a태그 사용해서 링크 연결한다.
.... <tr>
<td>{{e.idx}}</td>
<td>
<a href="detail?idx={{e.idx}}">{{e.name}}</a>
</td>
<td>{{e.tel}}</td>
<td>{{e.email}}</td>
<td>{{e.address}}</td>
</tr>
....
13) views.py에 def 추가
detail에 해당하는 모델을 선언한다.
addr은 detail 부분에 선언된 변수이다. primary key 값을 가지고 간다. 순번 idx와 수정/삭제를 거친 idv가 같을 때의 주소 목록이다.
#상세페이지
def detail(request):
idv = request.GET['idx']
#select * from address_address where idx = idv
addr = Address.objects.get(idx=idv)
return render(request,'address/detail.html',{'addr':addr})
14) detail.html 입력
값들을 {{addr.name}} 처럼 연결 후 onclick 으로 gourl() : addressList / update() : 수정 / del() : 삭제 script로 연결시킨다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>detail.html</title>
<style>
#wrap { width:450px; margin:auto }
#table { border-collapse: collapse; width:100% }
#th,td { padding:8px; text-align:left;
border-bottom: 1px solid #ddd;
}
tr:hover { background:#f5f5f5; cursor:pointer }
</style>
</head>
<body>
<div id="wrap">
<h1> detail 예제 </h1>
<form method="post" name="form1">
<!--사이트 위조 방지 설정이 기본적으로 설정 체크-->
{% csrf_token%}
<!--인덱스 번호는 숨김-->
<input type="hidden" name="idx" value="{{addr.idx}}">
<table>
<tr>
<td>이름</td>
<td><input type="text" name="name" value="{{addr.name}}"></td>
</tr>
<tr>
<td>전화번호</td>
<td><input type="text" name="tel" value="{{addr.tel}}"></td>
</tr>
<tr>
<td>이메일</td>
<td><input type="email" name="email" value="{{addr.email}}"></td>
</tr>
<tr>
<td>주소</td>
<td><input type="text" name="address" value="{{addr.address}}"></td>
</tr>
<tr>
<th colspan="2"> <!--버튼 추가-->
<input type="button" value="리스트" onclick="gourl()">
<input type="button" value="수정" onclick="update()">
<input type="button" value="삭제" onclick="del()">
</th>
</tr>
</table>
</form>
</div>
<script>
function gourl(){
location="/address/list"
}
function del(){
document.form1.action="delete";
document.form1.submit();
}
function update(){
document.form1.action="update";
document.form1.submit();
}
</script>
</body>
</html>
15) urls.py에 path 추가
path("detail", views.detail),
16) 수정/삭제기능 추가하기
- views.py 에 정의하기
# 삭제 기능
# csrf_protect는 csrf 방식을 검증한다.
# 앞으로 post 방식일 때는 반드시 사용을 원칙으로 한다.
@csrf_protect
def delete(request):
idv = request.POST['idx']
print("idx:", idv)
# delete * from address_address where idx = idv
# 선택한 데이터의 레코드가 삭제됨
addr = Address.objects.get(idx=idv).delete()
return redirect('/address/list')
# 수정 기능
@csrf_protect
def update(request):
id = request.POST['idx']
name = request.POST['name']
tel = request.POST['tel']
email = request.POST['email']
address = request.POST['address']
print("idx:", id)
print("name:", name)
print("tel:", tel)
print("email:", email)
print("address:", address)
- csrf 태그
@csrf_protect
csrf_protect는 csrf 방식을 검증한다.
앞으로 post 방식일 때는 반드시 사용을 원칙으로 한다.
- urls.py에 path 추가
(=detail.html에서 update 버튼이 클릭되었을 때 detail의 버튼이 눌리고(form1) 하단 스크립트가 실행된다.)
path("delete", views.delete),
path("update", views.update),
- 수정했을 때 콘솔창에 수정되는 것이 뜨는지 확인
- 수정 데이터 베이스 처리를 위해 idx를 갱신된 id로 바꿔주고 데이터 레코드 수정을 위해 save 처리한다.
# 수정 데이터 베이스 처리(idx=id -> 값을 넣으면 수정, 없으면 auto로 생성되므로 없어도됨)
addr = Address(idx=id, name=name, tel=tel, email=email, address=address)
# 데이터 레코드가 수정됨
addr.save()
return redirect('/address/list')
기능 구현 완료.
[Django 구동 순서]
config/urls(메인컨트롤러) > address/urls(컨트롤러) > views(모델) > html(뷰)
* 만들때는 반대로 만든 것.
[정리] 뷰(addressList.html)에서 Address List를 누르면 이동하게 만들 것. 그 기능을 구현하기 위해 모델(views.py)에서 요청을 응답하는 모델을 설정한다. 여기서 list를 정의하고 request를 return 한다. 컨트롤러 역할을 하는 urls에 AddressList와 연결된 링크를 누르면 리스트 파일로 옮겨갈 수 있게 그 리스트를 맵핑(Mapping) 해준다. ( 참고 )
'[ 빅데이터 ]' 카테고리의 다른 글
[빅데이터] 홈페이지 만들기(2) : 파이썬으로 로그인/로그아웃 데모 앱 만들기(오라클 연동) (0) | 2020.10.16 |
---|---|
[빅데이터] Django 오라클 연동 / 홈페이지 만들기(1) : 파이썬으로 회원가입 앱 만들기(아이디 중복확인) (0) | 2020.10.15 |
[ 빅데이터 ] c3js - 분석 결과 시각화하기, 파이차트 출력하기 (0) | 2020.10.14 |
[빅데이터] 리눅스 / 디장고(Django) 오라클 11g 설치, 연동 (0) | 2020.10.14 |
[빅데이터] 설문조사 앱 만들기(pycharm, Django) (1) | 2020.10.14 |
댓글