Django 소개 및 사용법

본 글은 http://tutorial.djangogirls.org/ko/ 의 튜토리얼 을 따라 블로그를 개발하고, 주요 정보들을 요약한 글입니다. 최종 결과물은 http://captainpangyo.pythonanywhere.com/ 에서 확인 가능합니다.

Django 란 무엇인가?

  • Django란 (/ˈdʒæŋɡoʊ/ jang-goh/쟁고/장고) 파이썬으로 만들어진 무료 오픈소스 웹 어플리케이션 프레임워크

Urlresolver

  • 역할 : 웹 서버에 요청이 오면 장고로 전달되고, 장고가 웹 페이지의 주소를 가져와 무엇을 할지 확인한다.
  • 각 URL 에 대해 일일이 확인하기는 비효율적이므로, 패턴으로 일치여부를 판단한다.
  • 일치하는 패턴의 경우 요청을 연관된 함수(view)에 넘긴다.
  • 결론 : urlresolver는 우체국의 우편 배달부 역할을 한다. (편지의 주소를 확인하고 맞으면 집에 전달해주는)

Django 설치

  • 가상환경 (Virtualenv) : 프로젝트 기초 전부를 Python/Django 와 분리시켜준다. 웹사이트가 변경되어도 개발 중인 것에 영향을 미치지 않는다.
  • 가상환경 만들기 : python3 -m venv myvenv myvenv 라는 가상환경을 생성
    • 명명법 : 소문자 / 공백은 없어야함 / 자주 입력해야 하므로 짧게
  • 가상환경 실행 명령어 : source myvenv/bin/activate
  • 가상환경에서 PIP로 장고 설치 : pip install django==1.8
  • 웹서버 실행 명령어 : python manage.py runserver
  • 장고 기본 Database : SQLite3
  • 파이썬 관습 : 던더(dunder; 더블 – 언더스코어 준말)
  • WSGI 프로토콜 : 파이썬을 이용한 웹사이트를 서비스 하기 위한 표준 (PythonAnywhere 에서 지원)

Django 프로젝트 생성

  • 가상환경에서 django-admin startproject mysite . 입력하여 장고 프로젝트 생성
  • 생성된 프로젝트의 초기 구조는
    djangogirls
    ├───manage.py
    └───mysite
          settings.py
          urls.py
          wsgi.py
          __init__.py
    
    • manage.py : 사이트 관리 및 웹 서버 실행
    • settings.py : 웹사이트 설정
    • urls.py : urlresolver 가 사용하는 패턴 목록 포함

Django 배포

  • Git 으로 커밋 및 배포
    [Local]
    - git status
    - git add --all .
    - git commit -m "First Commit."
    - git push
    
    [Server]
    - cd ~/my-first-blog
    - source myvenv/bin/activate
    - git pull
    - python manage.py collectstatic
    

Python 정규표현식

  • ^ : 문자열이 시작할 때
  • $ : 문자열이 끝날 때
  • \d : 숫자
  • + : 바로 앞에 나오는 항목이 계속 나올 때
  • () : 패턴의 부분을 저장할 때
  • 예를 들어, http://www.mysite.com/post/12345/ 와 같은 URL 이 있다고 하자.
  • 뷰마다 모든 글 번호를 작성하는 것은 현실적으로 힘들다.
  • 따라서 정규표현식 ^post/(\d+)/$. 을 이용하여 해당 글 번호를 가진 post 를 접근한다.
  • 위 정규표현식을 아래와 같이 부분 부분 나눠보면
    • ^post : url 시작점에 (오른쪽부터) post/ 가 있다.
    • (\d+) : 숫자가 1개 이상 있다.
    • / : / 뒤에 문자가 존재한다.
    • $ : URL 이 끝이 / 로 끝나야 매칭될 수 있다는 걸 의미
  • 파이썬에서 정규 표현식을 작성할 때는 항상 문자열 앞에 r을 붙입니다

Django View

  • 어플리케이션의 로직 을 넣는 곳
  • 모델의 정보를 받아와서 템플릿 에 전달하는 역할

템플릿 (HTML)

  • 서로 다른 정보를 일정한 형태로 표시할 수 있는 재사용이 가능한 파일
  • HTML : “Hyper Text Markup Language” 의 줄인 말.
  • 하이퍼텍스트(Hyper Text) : 페이지 간에 하이퍼링크를 담을 수 있는 텍스트
  • 마크업(Markup) : 브라우저 문서를 해석하는 표시

Django ORM & QuerySets

  • 쿼리셋 : 전달받은 모델의 객체 목록. 데이터베이스의 데이터를 읽어 필터 및 정렬 가능
  • 사용방법
    from blog.models import Post
    Post.objects.all()
    Post.objects.filter( title__contains = 'title' )
    
  • 쿼리셋은 연결(chaining) 도 가능
    Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
    

템플릿의 동적 데이터

  • from 다음의 마침표 .현재 디렉토리 또는 현재 어플리케이션 을 의미
    • from .models import Post : 현재 디렉토리의 models.py 를 접근 (.py 확장자는 붙이지 않아도 됌)
    from django.shortcuts import render
    from django.utils import timezone
    from .models import Post
    
    # `post_list` 라고 정의한 view 함수에서 QuerySet 으로 처리한 데이터를 `posts` 라는 변수로 받는다.
    def post_list(request):
    posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
    # QuerySet으로 받은 데이터를 posts 라는 이름의 변수에 태워 보낸다
    return render(request, 'blog/post_list.html', {'posts': posts})
    

Django 템플릿

  • 데이터 표현을 위해 template tags 라는 내장된 기능을 사용한다.
  • 장고 템플릿 태그(Django template tags) : 파이썬을 HTML로 바꿔주어, 빠르고 쉽게 동적인 웹사이트를 만들 수 있다.
  • 위에서 정의한 view 함수에서 전달받은 posts 를 다음과 같이 템플릿에 적용하면 동적 데이터를 다룰 수 있다.
    <div>
      <h1><a href="/">Django Girls Blog</a></h1>
    </div>
    
    {% for post in posts %}
      <div>
          published: {{ post.published_date }}
          <h1><a href="">{{ post.title }}</a></h1>
          {{ post.text|linebreaksbr }}
      </div>
    {% endfor %}
    

템플릿 확장하기

  • 서로 다른 페이지에서 HTML의 일부를 동일하게 재사용이 가능
  • post_list.html 에서 base.html 를 참조하는 방법
    <!-- base.html -->
    <div class="row">
      <div class="col-md-8">
      {% block content %}
      {% endblock %}
      </div>
    </div>
    
    <!-- post_list.html -->
    {% extends 'blog/base.html' %}
    
    {% block content %}
      {% for post in posts %}
          <div class="post">
              <div class="date">
                  {{ post.published_date }}
              </div>
              <h1><a href="">{{ post.title }}</a></h1>
              {{ post.text|linebreaksbr }}
          </div>
      {% endfor %}
    {% endblock content %}