django를 사용한 게시판

이지선·2023년 6월 12일

docker exec -it f4eada078c1c mysql -u root -p 1234

마이그레이션
python manage.py makemigrations
python manage.py migrate
python manage.py runserver

(선행)
https://github.com/maker-lee/django_board.git
pip install django
django-admin startproject board_project

-> 깃 연동
board_project 패키지가 생성된다.
기본 프로젝트의 역할 : 모든 프로젝트의 전체 설정을 담당함

manage.py : 웹서버 실행파일
default port 번호는 8000번
python manage.py runserver : 실행 코드

출력 화면)
June 12, 2023 - 15:51:02
Django version 4.2.2, using settings 'board_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

[12/Jun/2023 15:51:18] "GET / HTTP/1.1" 200 10664
Not Found: /favicon.ico
[12/Jun/2023 15:51:18] "GET /favicon.ico HTTP/1.1" 404 2117

주소 : http://127.0.0.1:8000
admin 기본 set인 admin page : http://127.0.0.1:8000/admin/login/?next=/admin/

urls.py : 모든 url 매핑

python manage.py startapp board_main

-> board_main 패키지가 생성된다.
기본 전체 프로젝트와 다르게 migrations,models,views가 생성된다.

migrations : 테이블 구성 변경 시 해당 폴더에 DDL쿼리 생성. (Data Definition Language)
Migration은 Django가 모델(즉, 당신의 데이터베이스 스키마)의 변경사항을 디스크에 저장하는 방법입니다

models.py : DB에 테이블의 구조와 똑같은 형태의 파이썬 CLASS를 만드는 파일. 장고에서는 models.py 파일을 통해 장고 웹 프레임워크에서 데이터베이스를 관리할 수 있습니다. 장고의 모델을 이용하면 파이썬으로 CRUD, 입력 폼, 관리자 페이지 등의 기능을 쉽게 구현할 수 있습니다

  • 만들고 싶은 테이블을 class를 통해 만들면 알아서 올려줌.

views.py : 사용자가 URL을 통해 요청할 때 URL과 MAPPING되는 파이썬 함수가 있는 파일

  • localhost:8080/author/new 를 했을 때, db에서 insert into author.. 이렇게 매핑해주는 공간이 urls인데 그 함수가 들어가는 공간이 views다.

board_project의 urls.py를 copy board_main에 paste

----- 230613 -----

선행)
python manage.py runserver

1. 웹서비스의 주요 형태

1) 테스트용 board_main > views_test.py 제작

기존 board_main > views_py 에서 아래 내용 삭제
def home(request) :
return render(request, 'test.html')

views_test.py 아래와 같이 코딩
※ get 요청 시 html 파일 그대로 return한다
def test_html(request) :
return render(request, 'test.html')

※ get 요청 시 html + data return
def test_html_data(request) :
return render(request, 'test.html')

urls.py 을 아래와 같이 수정

from . import views_test
urlpatterns = [
path('',views_test.test_html),
]

2) board_main 폴더에 test 폴더 / author 폴더 / post 폴더 생성

test 폴더에는 test.html을 이동시킴

3) viesw_test.py

※ get 요청 시 html 파일 그대로 return한다
def test_html(request) :
return render(request, 'test/test.html')
코딩을 수정함

※ get 요청 시 html + data return
def test_html_data(request) :
my_name = "Lee"
return render(request, 'test/test.html',{'name':my_name})
※ name:my_name을 딕셔너리 형태로 던져주게 된다.

-> render 주소를 잘 확인해야 한다. _ 과 .의 오타를 주의한다. T-T

4) 웹페이지에서 확인하기

f12 > network > Headers > General

URL:
Method:
Code : http 상태 코드 200 번대는 정상 / 300번대는 redirect코드 / 400번대 사용자 문제 / 500번대 서버 문제 , post는 대부분 300번대를 사용함. ex) 회원가입 후 summit을 하고 다른 곳으로 보내주지 않으면 성격급한 사용자가 계속 summit 시도함.

프론트엔드와 서버가 나누어져 있는 경우 상태 코드가 중요하다. 왜?
프론트엔드는 3000번 포트고 백엔드가 8000번 포트로 떠있는 경우, 지금 연습 하고 있는건 다 8000번대임

사용자와 서버 간에는 request와 response를 주고 받는다. 요청-응답
요청과 응답은 정해진 프로토콜(약속)에 의해 통신이 이루어져야 하고 이 프로토콜을 http 프로토콜이라고 한다.

header와 body로 이루어져있다.
hedaer에는 url, port 등 주요 요약정보가 담겨 있고
body에는 본문 내용이 담겨있다. get은 header에 요청하는 정보를 담고, post는 요청하는 정보를 body에 담는다. requset body는 내용 공개가 되지 않는다. header는 확인이 가능하다.

5) views_test.py에 from django.http import JsonResponse 추가

※ get 요청 시 html + data return
def test_Json_data(request) :
data = {
'name' : "Lee",
'age' : 20
}
return JsonResponse(data)
※ render는 웹개발에서 화면을 return해줄때 사용하는 용어다.
※ 그냥 리턴하면 파이썬의 자료 형태이므로 변환을 해줘야한다. 파이썬에 dict와 유사한 json형태로 변환해서 return한다.

6) views_test에 추가

※ get 요청 시 html + multi data return (json느낌의... 그러나 템플릿엔진인..)
def test_html_multi_data(request) :
data = {
'name' : "Lee",
'age' : 20
}
return render(request, 'test/test.html',{'data':data})
※ 'data' = key data = values
postman

urls.py에 path 추가
urlpatterns = [
path('',views_test.test_html_multi_data),
path('test_json',views_test.test_Json_data)
]

7) postman 다운로드 -> 안썼음

8) views_test.py 수정

※ 사용자가 get방식으로 쿼리파라미터 방식 데이터를 넣어놓을 때
※ 1. 쿼리 파라미터 방식 : localhost:8000/author?id=10&name=lee
※ 2. pathvariable 방식 (현대적인 방식) : localhost:8000/author/10
def test_html_parameter_data(request) :
id = request.GET.get('id')
name = request.GET.get('name')
print(id)
print(name)
return render(request, 'test/test.html',{})
※ GET방식 > get 꺼내온다 정보 안에서 id 정보를

urls.py에 path 추가
urlpatterns = [
path('',views_test.test_html_multi_data),
path('test_json',views_test.test_Json_data),
path('parameter_data',views_test.test_html_parameter_data),
]

http://127.0.0.1:8000/parameter_data?id=1&name=lee
화면은 없지만 print는 잘되면 성공

------------------------------------- 추가 ------------------------

manage.py : 장고를 실행하는데 필요한 진입점이다.
장고 실행 - runserver (터미널 : python manage.py runserver)
앱 프로젝트 생성 - startapp
데이터베이스 생성 - makemigrations, migrate
관리자 계정 생성 - createsuperuser

1. 테스트용 제작

각 의미

templates : 템플릿.... 웹페이이제 직접 보여줄 html 파일을 보관하는 폴더
board_main에 templates 폴더를 생성하여, 하위 폴더로 author,post,test 폴더를 생성함
test 폴더에 화면에 뿌려주는 웹페이지 test.html 를 생성함

2. 파일

1) test.html 웹페이지를 작성한 곳

뿌려주는 방식이 3가지임

<!--단일 data를 넣어올 때-->
<!-- <h1>{{name}} welcome</h1>

dict에 multi data를 넣어올때 
<h1>{{data.name}} Welcome ! </h1>
<h1>{{data.age}} </h1> 

사용자가 get방식으로 넘긴 data를 받아올때-->    
<!-- <h1>{{data.name}} Welcome ! </h1>
<h1>{{data.email}} </h1> 
<h1>{{data.password}} </h1> 

2) urls.py는 웹 접근 시 이용하는 URL경로를 정의하는 파일

path('주소',뷰.함수명)으로 입력한다.
사용자의 이벤트에 따라서 http://127.0.0.1:8000/parameter_data 이렇게
/주소로 이동하게 된다.

from django.urls import path
from . import views_test <- 추가했다.

urlpatterns = [
path(' ',views_test.test_html_multi_data),
path('test_json',views_test.test_Json_data),
path('parameter_data',views_test.test_html_parameter_data),
]

3) views_test.py 화면에 출력하는 기능이 들어간다.

urls에서 views의 경로를 지정함
파이썬 문법을 활용하여 함수들을 생성아며, 함수들을 이용하여 원하는 형태로 데이터를 처리한뒤 html로 데이터를 보낸다.
render(함수 및 페이지에 대한 requrest값, 읽어올 html 문서 경로, 함께 전해줄 데이터의 딕셔너리) 데이터값을 받아온 뒤 html로 데이터를 보낸다.

from django.shortcuts import render <- 패키지에 있는 함수로서 첫번째 파라미터로 request를, 그리고 두번째 파라미터로 템플릿을 받아들인다.
from django.http import JsonResponse <- 입력 HttpResponse의 subclass로, JSON-encoded response를 생성할수 있게 해준다. JsonResponse는 response를 커스터마이징 하여 전달하고 싶을때, http status code에 더하여 메세지를 입력해서 전달할 수 있다.
from django.shortcuts import render, redirect
from django.http import JsonResponse, HttpResponse

#Create your views here.
#get 요청 시 html 파일 그대로 return한다
def test_html(request) :
return render(request, 'test/test.html')
#get 요청 시 html + data return
def test_html_data(request) :
my_name = "Lee"
return render(request, 'test/test.html',{'name':my_name})
#name:my_name을 딕셔너리 형태로 던져주게 된다.
#get 요청 시 html + multi data return (json느낌의... 그러나 템플릿엔진인..)
def test_html_multi_data(request) :
data = {
'name' : "Lee",
'age' : 20
}
return render(request, 'test/test.html',{'data':data})
#'data' = key data = values
#get 요청 시 html + data return
def test_Json_data(request) :
data = {
'name' : "Lee",
'age' : 20
}
return JsonResponse(data)
#render는 웹개발에서 화면을 return해줄때 사용하는 용어다.
#그냥 리턴하면 파이썬의 자료 형태이므로 변환을 해줘야한다. 파이썬에 dict와 유사한 json형태로 변환해서 return한다.
#사용자가 get방식으로 쿼리파라미터 방식 데이터를 넣어놓을 때
#1. 쿼리 파라미터 방식 : localhost:8000/author?id=10&name=lee
#2. pathvariable 방식 (현대적인 방식) : localhost:8000/author/10
def test_html_parameter_data(request) :
id = request.GET.get('id')
name = request.GET.get('name')
print(id)
print(name)
return render(request, 'test/test.html',{})
#GET방식 > get 꺼내온다 정보 안에서 id 정보를
#사용자가 get방식으로 쿼리파라미터 방식 데이터를 넣어놓을 때
#1. 쿼리 파라미터 방식 : localhost:8000/author?id=10&name=lee
def test_html_parameter_data(request) :
myname = request.GET.get('name')
email = request.GET.get('email')
password = request.GET.get('password')
data = {
'name':myname,
'email' : email,
'password' : password
}
return render(request, 'test/test.html',{'data':data})
#그냥 리턴하면 파이썬의 자료 형태이므로 변환을 해줘야한다. 파이썬에 dict와 유사한 json형태로 변환해서 return한다.
#변수를 선언하고, data 변수를 다시 선언해서 {}로 담는다. return은 여러개를 하는게 아니라 data 하나만 하는건데 아니 이걸 어떻게 알아요 ㅜㅜ
아래서 파라미터 데이터는 urls에 나오는 주소 이름이고, urls는 views_test의 함수명을 사용한다.
http://127.0.0.1:8000/parameter_data?name=lee&email=js@naver.com&password=1234

#사용자가 get방식으로 쿼리파라미터 방식 데이터를 넣어놓을 때
#2. pathvariable 방식 (현대적인 방식) : localhost:8000/author/10
def test_html_parameter_data2(request, my_id) :
print(my_id)
return render(request, 'test/test.html',{})

주소 변경
http://127.0.0.1:8000/parameter_data2/1234

#form 태그를 활용한 post 방식
#화면을 rendering(화면 리턴) 해주는 method 필요
def test_post_form(request):
return render(request, 'test/test_post_form.html')

#POST방식
def test_post_handle(request):
name = request.POST['user_name']
email = request.POST['user_email']
password = request.POST['user_password']
print(name)
print(email)
print(password)
return redirect('/') # http://localhost:8000/ 으로 이동해라
#post 요청은 요청 후 적절한 상태코드를 줘야 한다.get처럼 html 화면 응답을 줄게 없으니 200 이런거. return HttpResponse('가입을 축하드립니다')

------------------------------ 추가 ---------------------------------

DB에 내용 쌓기

선행) docker 연동하고 스키마 생성

powershell 입력 -> docker exec -it f4eada078c1c mysql -u root -p 1234
create database board; 스키마 생성

1) settings.py 에 DB정보 입력 / 스키마는 미리 sql에서 생성해야함.

전체 프로젝트의 database 정보를 아래에서 설정함
db의 종류(mySql),host, port, mySql의 계정/pw, 스키마명(NAME) 필요
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'board',
'USER' : 'root',
'PASSWORD' : '1234',
'HOST' : '127.0.0.1',
'PORT' : '3306',
}
}

2) 파이썬의 class를 통해서 테이블은 자동생성(스키마는 자동생성 X)

파이썬 객체와 DB의 싱크를 맞추고(= models.py) 별도의 raw 쿼리 없이 db를 컨트롤 하는 것을 ORM 이라고 한다.
ORM은 Object Relational Mapping(객체-관계-매핑)의 약자이다. ORM은 객체와 데이터베이스의 관계를 매핑해주는 도구이다. ORM은 프로그래밍 언어의 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 도구이다.

models.py의 클래스와 DB의 table과 sync를 맞춰 테이블 컬럼정보 자동생성된다.

코딩 방식 : class name = table name , 변수 = column name

class Test(models.Model):
name = models.CharField(max_length=20)
email = models.CharField(max_length=20)
password = models.CharField(max_length=20)

3) sql을 사용하기 위해서 pip 모듈 설치

pip install mysqlclient

4) database migrations (좀더 낫다고 여겨지는 다른 운영환경으로 옮겨가는 과정을 말한다)

4-1) python manage.py makemigrations

models.py 내용이 마이그레이션 폴더에 추가되어있다.

4-2) python manage.py migrate

DDL 생성 후 반영 , DB와 커넥션을 맺으면서 활동 시작

4-3)python manage.py showmigrations

프로젝트의 마이그레이션에 대해 적용 여부 확인

주의사항 : 적용된 마이그레이션 파일은 절대로 삭제하시면 안됩니다. 각 마이그레이션은 이전 버전에 대해 의존성을 가지기 때문에 DB 전체가 뻑날 수 있으므로 마이그레이션 파일을 삭제려면 반드시 적용을 해제하고 삭제하셔야 합니다.
예를 들어
0001initial
0002_auto
....
이 때 0002 마이그레이션 파일을 삭제하고 싶다면
1. python manage.py migrate app_name 0001 명령어로 이전 버전으로 적용시킨후 삭제
2. python manage.py migrate app_name zero 명령어로 마이그레이션을 초기화 시킨 수 삭제
둘 중 하나의 절차를 거친 후 삭제

========================================================================

사전 준비)
python manage.py runserver
docker에서 mysql 실행, use board까지해야함.

1. INSERT (python에서 mysql 연동)

1) views_test.py

models.py 에서 Test class를 만들었음
class Test(models.Model):
name = models.CharField(max_length=20)
email = models.CharField(max_length=20)
password = models.CharField(max_length=20)

models에서 Test라는 모듈을 다운로드 받음
from .models import Test

#POST방식 urls에 path('test_post_handle',views_test.test_post_handle) 로 연결된다.
def test_post_handle(request):
if request.method == 'POST' :
user_name = request.POST['user_name'] # post에서 하나씩 꺼내서
user_email = request.POST['user_email']
user_password = request.POST['user_password']

    DB에 insert -> save 함수를 사용함 .
    DB에 테이블과 sync가 맞는 Test클래스에서 객체를 만들어서 save

    t1 = Test() # class를 깡통으로 만들고
    t1.name = user_name # 이렇게 집어넣는 스타일로 함 
    t1.email = user_email
    t1.password = user_password
    t1.save()
    return redirect('/') 

else : # GET방식
   return render(request, 'test/test_post_form.html')

2) DB에 잘 들어갔는지 확인하기

http://localhost:8000/test_post_handle -> 입력 -> select * from board_main_test;

2. SELELCT 만들기

단일 조회 / 모두 조회 / 조건에 맞는 내용만 조회

1) views_test.py에 함수 추가

#DB에서 조회하기
def test_select_one(request,my_id) : # 하나만 조회하기, 단 건 조회는 get()함수
t1 = Test.objects.get(id=my_id)
return render(request, 'test/test_select_one.html',{'data':t1})

def test_select_all(request) : # 전체 조회하기, 모든 data조회는 post, select * from ..; all()함수를 사용한다. 파라미터 받을 필요 없음
tests = Test.objects.all()
return render(request, 'test/test_select_all.html',{'datas':tests})

#WHERE 조건으로 조회할 때는 filter() 함수를 사용한다.
def test_select_filter(request) :
my_name = request.GET.get('name')
tests = Test.objects.filter(name=my_name)
return render(request, 'test/test_select_filter.html',{'datas':tests})

2) urls에 path 추가

path('test_select_one/<int:my_id>',views_test.test_select_one), # 조회한다는 뜻은 where 조건이 있는 것이니까... <>에 값이 들어가야함. 일단 유일한 값인 pk값 지정. 
path('test_select_all',views_test.test_select_all),
path('test_select_filter',views_test.test_select_filter),

3-1) test_select_one.html 만들기

{{data.name}} Welcome !

{{data.email}}

{{data.password}}

테스트(one) : http://localhost:8000/test_select_one/1

3-2) test_select_all 만들기 / test_select_filter 만들기

<!--반복문을 사용하여 출력하기, 파이썬 템플릿엔진 문법-->
{% for data in datas %}
<h1>닉네임 : {{data.name}} Welcome ! </h1>
<h1>메일 : {{data.email}} </h1> 
<h1>비밀번호 : {{data.password}} </h1>     
{% endfor %} <!--for문 종료-->

테스트(all) : http://localhost:8000/test_select_all
테스트(filter) : http://localhost:8000/test_select_filter?name=kim

3. UPDATE 만들기

UPDATE를 하기 위해서는 해당 건을 조회하기 위한 ID값이 필요하다. (수정이니까~)
메소드는 등록과 동일하게 save()를 사용한다. save는 id가 있으면 update, 없으면 insert

1) views_test.py

#UDATE 하기
def test_update(request):
if request.method == 'POST' :
my_id = request.POST['my_id'] # my_id로 id가 작성한 '기존 객체' 조회
t1 = Test.objects.get(id=int(my_id)) # db에서 객체를 조회해서 가져오기
user_name = request.POST['user_name'] # 사용자가 입력한 값으로 업데이트
user_email = request.POST['user_email']
user_password = request.POST['user_password']
print(type(my_id))

    t1.name = user_name 
    t1.email = user_email
    t1.password = user_password
    t1.save() # 기존 건이 있으면 update가 되고 없으면 insert가 된다. 
    return redirect('/') 
else : 
   return render(request, 'test/test_update.html')

2) test_update.html 생성

            id : <input type="text" name="my_id"> <br>
            이 름 : <input type="text" name="user_name"> <br>
            이메일 : <input type="email" name="user_email"> <br>
            패스워드 : <input type="password" name="user_password"><br>

3) urls 추가

path('test_update',views_test.test_update), 

4. DELETE 만들기

delete() 함수 사용. 삭제는 UPDATE와 비슷해서 조회한 뒤 DELETE, POST 요청이다.

def test_update(request):
if request.method == 'POST' :
my_id = request.POST['my_id']
t1 = Test.objects.get(id=my_id)
t1.delete() <- 이 부분 수정
return redirect('/')

profile
Data Analyst

0개의 댓글