본문 바로가기
[ 빅데이터 ]

[빅데이터] PyCharm, 디장고(Django) 설치 / 주소록 앱 만들기

by 히앤님 2020. 10. 12.
반응형
SMALL

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 .

 

설치 후 manage.py 파일이 생김

 

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 [생성할 앱 이름]

 

'address' 라는 이름의 앱을 생성했다.

 

 

4. sqlitestudio 리눅스 버전 파일 설치

https://github.com/pawelsalawa/sqlitestudio/releases

 

Releases · pawelsalawa/sqlitestudio

A free, open source, multi-platform SQLite database manager. - pawelsalawa/sqlitestudio

github.com

 

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'

index > addressList로 이동

 

 

# 등록버튼을 누르면 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.pyaddressWrite 등록하기

뷰에 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),

 

이런 식으로 path 추가해주기

 

9) 데이터 입력 후 전송하기

 

질의 보내기(submit)

 

 

[에러] csrf 검증에 실패했습니다.

Django는 CSRF(cross site Request Forgery) 사이트 위조 방지 설정이 기본적으로 설정 체크하게 되어있다.

 ex) 해커들이 사이트를 동일하게 꾸며서 정보 빼내는 것 등을 방지하기 위해 FORM을 전송할 때 랜덤으로 생긴 검증을 맞춰야 전송된다.

{% csrf_token%}

 따라서 이같은 코드를 항상 추가해주어야 한다.(addressWrite.html에 추가)

csrf 검사 추가

 

10) 결과

좌 : addressList 우: admin에 잘 들어감

 

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),

 

detail.html

 

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) 해준다. ( 참고 )

 


주소록 구조 정리
상세보기

반응형
LIST

댓글