웹 프로그래밍/[ Django ]

[ Django ] 00. Django 알아보기

kim.svadoz 2020. 8. 11. 09:23
728x90
반응형

django

파이썬으로 이루어진 WEB 프레임워크.

django의 성격

  • 파이썬을 이용하기 때문에 개발 속도가 빠르다.
  • 프레임워크라는 것은? ----> 프랜차이즈의 성격을 갖는다 ( 내가 다 줄테니 너넨 사용만 해라~ )

why django?

  • 풍부한 언어와 프레임워크 사용 경험을 배양하기 위함.

MTV

스프링의 MVC패턴과 같은 패턴임

Model - Template(사용자가 보는 화면) - View(중간 관리자)

image-20200610100316308

  • URLs: 단일 함수를 통해 모든 URL 요청을 처리하는 것이 가능하지만, 분리된 뷰 함수를 작성하는 것이 각각의 리소스를 유지보수하기 훨씬 쉽습니다. URL mapper는 요청 URL을 기준으로 HTTP 요청을 적절한 view로 보내주기 위해 사용됩니다. 또한 URL mapper는 URL에 나타나는 특정한 문자열이나 숫자의 패턴을 일치시켜 데이터로서 뷰 함수에 전달할 수 있습니다.
  • View: view는 HTTP 요청을 수신하고 HTTP 응답을 반환하는 요청 처리 함수입니다. View는 Model을 통해 요청을 충족시키는 데 필요한 데이터에 접근합니다. 그리고 탬플릿에게 응답의 서식 설정을 맡깁니다.
  • Models: Model은 application의 데이터 구조를 정의하고 데이터베이스의 기록을 관리(추가, 수정, 삭제)하고 query하는 방법을 제공하는 파이썬 객체입니다..
  • Templates: 탬플릿은 파일의 구조나 레이아웃을 정의하고(예: HTML 페이지), 실제 내용을 보여주는 데 사용되는 플레이스홀더를 가진 텍스트 파일입니다. view는 HTML 탬플릿을 이용하여 동적으로 HTML 페이지를 만들고 model에서 가져온 데이터로 채웁니다. 탬플릿으로 모든 파일의 구조를 정의할 수 있습니다.탬플릿이 꼭 HTML 타입일 필요는 없습니다!

Django Intro

Strat Django

  1. 장고 설치하기
pip install djang==2.1.15
pip list
  1. 프로젝트 생성
django-admin startproject <프로젝트 명>
python manage.py runserver
  1. 프로젝트 생성시 제공되는 파일
    • manage.py
      • 현재 django와 관련된 모든 명령어를 manage.py를 통해 실행합니다.
    • __init__.py
      • 현재 __init__.py 파일이 존재하는 폴더를 하나의 프로젝트 혹은 패키지로 인식시키게 해주는 파일
    • settings.py
      • 현재 프로젝트의 전체적인 설정 및 관리를 위해 존재하는 파일
    • urls.py
      • 내 프로젝트에 접근할 수 있는 경로를 설정하기 위한 파일
    • wsgi.py
      • ??배포용??

Start App

1. Application 생성

python manage.py startapp pages(프로젝트 명)
  • setting.py에서 application 출생신고(?) 및 설정하기

image-20200609163627886image-20200609163824929

  • 다시 서버 시작해보기
cd intro/
python manage.py runserver

image-20200609164007909

언어(한글) 및 시간(서울) 설정 완료!

2. urlPattern 및 View, Template 설정

  • url. py : 경로설정

image-20200610094001890

  • views.py : 함수설정

image-20200610094119658

  • templates 안에 html파일 생성

image-20200610094359900

{{ }} 안에 value 값을 넣어준다~

image-20200610094441250

!!!

  • 이렇게 key값과 value형태인 dictionary로 사용가능하다!

image-20200610101459650image-20200610101543298

  • 조금 더 깔끔하게 작성하기.

image-20200610102608265image-20200610102620796

  • url에서 입력을 받을 때 특정 문자/숫자만 요청할 수 있다.

image-20200610111540035

Q1

# urls.py
path('urlcopy/<str:name>/<int:age>', views.urlcopy)

# views.py
def urlcopy(request, name, age):
    name = name
    age = age
    context={
        'name' : name,
        'age' : age
    }
    return render(request, 'urlcopy.html', context)


# urlcopy.html
<h2>URL로 입력받은 이름 : {{name}}, 나이 : {{age}}</h2>

image-20200610112032946

Q2

# urls.py
path('multiply/<int:num1>/<int:num2>', views.multiply)

# views.py
def multiply(request, num1, num2):
    num1 = num1
    num2 = num2
    result = num1 * num2
    context = {
        'num1' : num1,
        'num2' : num2,
        'result' : result
    }
    return render(request, 'multiply.html', context)

# multiply.html
URL로 받은 숫자1 : {{num1}} , 숫자2 : {{num2}}

곱한 값 => {{result}}

image-20200610113316969

Q3

# urls.py
path('multipletable/<int:big>/<int:small>', views.multipletable),

# views.py
def multipletable(request, big, small):
    result = []
    if(big < small):
        big, small = small, big
    for num in range(1, small+1):
        result.append(big*num)
    context={
        'result' : result
    }
    return render(request, 'multipletable.html', context)

# multiplly.html
<p>{{result}}</p>
<h1>Django Temlplate Lagnuage ( DTL )</h1>

<!--  -->
{# 이게 DTL의 주석 #}
{% comment %}
DTL의 주석은 개발자모드(F12) 에서도 보이지 않는다!
여기는 전부
출력이 안됨... 주석임!
되도록이면 template에서는 주석사용 XX
{% endcomment %}

{% for num in result %}
  <p>{{num}}</p>
{% endfor %}

image-20200610131929723

3. DTL 사용해보기

# urls.py
path('dtl/', views.dtl),

# views.py
def dtl(request):
    mList = ['짜장면', '차돌짬뽕', '탕수육', '콩국수']
    empty_list = []
    mString = "Life is short, You need Python"
    today = datetime.now()
    context = {
        'mList' : mList,
        'empty_list' : empty_list,
        'mString' : mString,
        'today' : today
    }
    return render(request, 'dtl.html', context)

# dtl.html
<h1>1. for문</h1>
{% for food in mList %}
  <p> {{ forloop.counter }}.{{ food }} </p>
{% endfor %}

{% for data in empty_list %}
  <p>data</p>
{% empty %}
  <p>비어있습니다.</p>
{% endfor %}
<hr>

<h1>2. 조건문</h1>
{% for food in mList %}
  {% if food == '짜장면' %}
    <p>짜장면엔 고춧가루지 아암 이게맞지</p>
  {% else %}
    <p>뭔 소리야 {{ food }}을 먹어줘야지</p>
  {% endif %}
{% endfor %}
<hr>

{% for food in mList %}
  {% if forloop.first %}
    <p> {{forloop.first}} </p>
    <p> {{forloop.last}} </p>
    <p>짜장면엔 고춧가루지 아암 이게맞지</p>
  {% else %}
    <p>뭔 소리야 {{ food }}을 먹어줘야지</p>
  {% endif %}
{% endfor %}

<h1>3. filter 활용</h1>
  <p>{{ mString|lower }}</p>
  <p>{{ mString|upper }}</p>
  <p>{{ mString|title }}</p>
  <p>{{ mString|length }}</p>
  <p>{{ mString|truncatewords:3 }}</p>
  <p>{{ mString|truncatechars:10 }}</p>
<hr>

<h1>4. lorem ipsum</h1>
<p>{% lorem %}</p>
<p>{% lorem 3 w %}</p>
<p>{% lorem 3 p %}</p>

image-20200610134054558image-20200610142052635

  • advanced 조건문, 반복문
# urls.py
path('forif/', views.forif),

# views.py
# 1. 간단한 반복문으로 리스트 각 요소를 출력
# 2. if, else 활용해서 문자열 비교
# 2-1. 내가 넘긴 문자열과 특정한 문자열 비교
# 3. if, elif, else 사용해보기
# 3-1. 문자열의 길이가 5 이하이면 short
# 3-2. 문자열의 길이가 10 이상이면 long
# 3-3. 모두 아니면 적당 출력

# 모두 작성했다면,
## 1) 반복문으로 리스트 각 요소를 출력해서
## 2) 해당 요소가 90 이상이면 A
## 3) 해당 요소가 70 이상이면 B
## 4) 그 외엔 C 출력
def forif(request):
    mList = [100, 50, 80, 71, 10]
    mString = '간단한 문자열zzzzzzzzzzzz'
    mInput = input("문자열을 입력하세요: ")
    data_a = '첫번째 데이터'
    data_b = '두번째 데이터'
    data_a, data_b = data_b, data_a
    context = {
        'mList' : mList,
        'mString' : mInput,
        'data_a' : data_a,
        'data_b' : data_b
    }
    return render(request, 'forif.html', context)

# forif.html
<h1>간단한 반복문으로 리스트 출력</h1>
{% for data in mList %}
  {% if data >= 90 %}
  <P>{{ data }} : A</P>
  {% elif data >= 70%}
  <P>{{ data }} : B</P>
  {% else %}
  <p>{{ data }} : C</p>
  {% endif %}
{% endfor %}
<hr>

<h1>문자열의 길이</h1>
{% if mString|length <= 5 %}
  <p>{{ mString|title }} : short</p>
{% elif mString|length >= 10 %}
  <p>{{ mString|title }} : long</p>
{% else %}
  <p>{{ mString|title }} : 적당</p>
{% endif %}

image-20200610150956879

Django form태그 사용

  • 프로젝트 기획 단계에서는 페르소나 를 중시해라!
  • form 태그는 기본이 GET방식!
  • 가져오는 방식이 2가지
    • [] ---> 값이 없을 때 오류 발생
    • .get ---> 값이 없어도 오류 발생 안함. 값이 없으면 none 출력
      • request.GET == 딕셔너리와 유사하다.
      • request.GET != dict()
print(request.GET['message'])
print(request.GET.get('message'))

절대경로? 상대경로?

  • 절대경로 : 파일이 같이 올라가도 C:\에서 시작하는 그 경로로 접근할 수 없어서 이미지가 깨진다.
  • 상대경로 : 루트경로로부터 작성된 경로로 찾아가기 때문에 해당 위치에 이미지가 있으면 찾을 수 있다.

Q1

# 1. 사용자가 숫자 입력
# 2. 입력 받은 횟수 만큼 반복해서
# 3. 리스트에 로또 번호 담는다.
# 3-1. random.sample(range(1, 46), 6)
# 4. 사용자가 입력한 숫자와 로또번호가 담긴 리스트를 출력
# 5. ul태그를 사용하여 각 번호들을 한줄 씩 출력
# urls.py
path('lottoT/', views.lottoT),
path('lottoC/', views.lottoC),

# views.py
def lottoT(request):
    return render(request, 'lottoT.html')

def lottoC(request):
    num = int(request.GET.get('num'))
    lottos = []
    for data in range(num):
        lottos.append(random.sample(range(1, 46), 6))
    context={
        'num' : num,
        'lottos' : lottos,
    }

    return render(request, 'lottoC.html', context)

# lottoT.html
<h1> 로또 번호를 입력해주세용~ </h1>
<form action="/lottoC/">
  <label for="buy"> 구매 하고자 하는 갯수 : </label>
  <input type="number" name="num" id="buy">
  <input type="submit" value="제출" >
</form>

# lottoC.html
<h1> 결과는? </h1>
<p>로또를 {{num}}개 구매하셨습니다.</p>
<ul>
  {% for lotto in lottos %}
  <li>{{ lotto }}</li>
  {% endfor %}
</ul>

Second App

경로 분리하기

  • 기존의 pages Application에 있던 urls의 view는 pages폴더 하위로 이사한다.
  • # urls.py ( project ) from django.contrib import admin from django.urls import path, include urlpatterns = [ path('secondapp/', include('secondapp.urls')), path('pages/', include('pages.urls')), path('admin/', admin.site.urls), ] # urls.py ( pages ) from django.urls import path from . import views urlpatterns = [ path('index/', views.index, name="index"), path('hello/', views.hello, name="hello"), path('name/', views.name, name="name"), path('introduce/', views.introduce, name="introduce"), path('classRandomChoice/', views.classRandomChoice, name="classRandomChoice"), path('yourname/<str:name>/', views.yourname, name="yourname"), path('urlcopy/<str:name>/<int:age>', views.urlcopy, name="urlcopy"), path('multiply/<int:num1>/<int:num2>', views.multiply, name="multiply"), path('multipletable/<int:big>/<int:small>', views.multipletable, name="multipletable"), path('dtl/', views.dtl, name="dtl"), path('forif/', views.forif, name="forif"), path('loop/', views.loop, name="loop"), path('throw/', views.throw, name="throw"), path('catch/', views.catch, name="catch"), path('lottoT/', views.lottoT, name="lottoT"), path('lottoC/', views.lottoC, name="lottoC"), path('artii/', views.artii, name="artii"), path('result/', views.result, name="result"), ]
  • 추후에 페이지가 커지고 원활한 유지보수를 위해 path 경로에 name을 지정할 수 가 있다.
    • 경로가 바뀌더라도 form태그나 경로로 무언가를 요청하던 일이 있을 때 이름으로 지정하기.
    ex)
  • # urls.py path('catch/', views.catch, name="catch"), # html #### 원래는 "/pages/catch/" #### <form action="{% url 'catch' %}" method="GET"> 이름 : <input type="text" name="name"> 나이 : <input type="number" name="age"> <input type="submit" value="제출"> </form>
  • 장고는 자동으로 templates 폴더를 가서 index를 가져온다.
    • settings와 urls에서 먼저 선언한것을 먼저 찾아옴
    • 따라서 모든 html을 templates 하위에 앱이름으로 폴더를 생성하고 옮겨준다.
    • views에 html을 return하는 부분에도 경로 수정하기.
    ex)
  • return render(request, 'pages/index.html', context)

base bootstrap 설정

  • 베이스 페이지를 만들기 위해 프로젝트에 templates 폴더를 만들고 html에 부트스트랩 적용
  • base.html

image-20200613142000567

  • setting.py

image-20200613142820935

=> mysite에 있는 템플릿을 베이스로 사용하겠다!!

  • 다른 app에 있는 html에서 베이스로 지정되있는 템플릿을 extends 하여 사용할 수 있다.

image-20200613142247147

static 설정

  • 폴더 구조가 바뀌면 서버를 껐다 켜주자!!
  • image와 같은 정적 파일을 사용하기 위해 template과 같은 위치에 static폴더 생성하기
    • setting.py
    image-20200613153426971
    • html
    image-20200613153350207

링크로 다른 앱 넘어가기

  • urls.py에 app_name을 설정해주고 해당 app_name을 통해 페이지를 연결

image-20200613161415674image-20200613161435318image-20200613161454569

728x90
반응형