주로 로직이 간단한 뷰를 구성할 때 함수형 뷰를 이용하여 신속하게 개발한다.

 

-Views.py

from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404,render
from django.urls import reverse
from polls.models import Question, Choice

# 요청을 처리할 함수형 뷰의 인자는 request 를 가지고 있어야 한다.
def index(request):
    # Question 테이블에서 전체 레코드를 검색하여 pub_date 컬럼을 오름차순으로 정렬하여 마지막 5개 즉, 최근 5개를 가져옴
    latest_question_list = Question.objects.all().order_by('-pub_date')[:5]
    # 최근 5개의 리스트를 template 에게 넘겨주기 위해 딕셔너리 생성
    context = {'latest_question_list': latest_question_list}
    # render(요청 받은 request, 템플릿 파일, 전달할 데이터)
    return render(request, 'polls/index.html', context)


def detail(request, question_id):
    # URLconf 에서 설정된 question_id를 사용하여 해당 레코드가 존재하지 않으면 Http 404 익셉션을 발생  
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})


def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    # 폼의 데이터에 choice가 없으면 KeyError, 테이블에 해당 레코드가 없다면 DoesNotExist 
    except (KeyError, Choice.DoesNotExist):
        return render(request, 'polls/detail.html',{
            'question': question,
            'error_message': "선택한 선택지가 없습니다."
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # 리다이렉트 설정
        # reverse 함수를 사용하면 URLconf 에서 설정했던 name(별명)을 가지고 역으로 해당 URL로 변환한다.
        return HttpResponseRedirect(reverse('polls:results', args=(question_id,)))


def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request,'polls/results.html', {'question': question})

-urls.py

from django.urls import path
from polls import views

app_name = 'polls'
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
    path('<int:question_id>/vote', views.vote, name='vote'),
    path('<int:question_id>/results', views.results, name='results'),
    path('yourname/', views.get_name, name='yourname'),
]

path 함수를 이용하여 URL패턴, 적용할 뷰의 함수, 별명(name)을 지정할 수 있다.

별명은 reverse 함수나 template에서 다른 뷰로 로직이 이동할 때 주로 사용하여 URL를 하드코딩하는 불편함을 없애준다.

 

  • 요청에 들어있는 URL이 urls.py 파일에 정의된 URL 패턴과 매칭되는지를 분석한다.
# 프로젝트의 urls.py
from django.contrib import admin
from django.urls import path, include
from djangoProject.view import AboutView
urlpatterns = [
    path('admin/', admin.site.urls),
    path('about/', AboutView.as_view()),
    path('polls/', include('polls.urls')),
    path('books/', include('books.urls')),

]

 

  • settings.py 파일의 ROOT_URLCONF 항목을 통해 최상의 URLconf(urls.py)의 위치를 설정한다.
  • urlpatterns 변수에 지정되어 있는 URL 리스트를 확인한다.
  • 우선 순위는 위에서부터 아래순이다.
  • 매치된 URL의 뷰를 호출. 뷰는 함수 또는 클래스의 메소드이다. 호출 시 HttpRequest 객체와 그리고, 매칭할 때 추출된 단어를 뷰로 넘겨준다.
  • URL 매칭에 실패하면 에러를 처리하는 뷰를 호출한다. 

 

-URLconf의 계층화

path('polls/', include('polls.urls')),
# 프로젝트 하위의 app의 urls.py
from django.urls import path
from polls import views

app_name = 'polls'
urlpatterns = [
    path('', views.index, name='index'),
    path('<int:question_id>/', views.detail, name='detail'),
    path('<int:question_id>/vote', views.vote, name='vote'),
    path('<int:question_id>/results', views.results, name='results'),
    path('yourname/', views.get_name, name='yourname'),
]

프로젝트 urls.py에서 app urls.py를 include를하면 계층화 하여 관리할 수 있다. 이와 같이 구성하면 변경도 쉬워지고, 확장도 용이하다.

1개의 URLconf로 코딩하는 경우 app_name등이 변경될 경우 모든 패턴의 URL를 변경해야하지만 2개의 URLconf로 구성할 경우  상위 URLconf에서 하나의 패턴만 수정하면 된다.

 

 

- Path Converter

꺽쇠 부분(<>)을 말하는데. 기본적으로 제공하는 타입이 있고ㅡ 개발자가 추가로 타입을 등록할 수도 있다.

  • str: /(슬래시)를 제외한 모든 문자열과 매치된다. 타입이 지정되지 않았다면 디폴드로 str 타입을 사용
  • int: 0 또는 양의 정수와 매치된다. 매치된 정수를 파이썬의 int 타입으로 변환
  • slug: slug 형식의 문자열(ASCII, 숫자, 하이픈, 밑줄로만 구성됨)과 매치
  • uuid: UUID 형식의 문자열과 매치, 매치된 문자열은 파이썬은 UUID 타입으로 변환
  • path: /(슬래시)를 포함한 모든 문자열과 매치된다. 이는 URL 패턴의 일부가 아니라 전체를 추출하고자 할때 많이 사용한다.

- 정규 표현식(Regular Expression)

from django.urls import path, re_path

from . import views

urlpatterns = [
	path('articles/2003/', views.special_case_2003),
    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    re_path(r'^articles/(?p<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$', views.article_detail),
]

(?P적용할 패턴)을 작성한다.

ex) r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<slug>[\w-]+)/$'

artlcles로 시작하고 year는 0부터 9까지의 4자리의 정수이고 month는 0부터 9까지의 2자리 정수 slug는 영문, 숫자 , 밑줄(_), 하이픈(-)  한 개 1번 이상 반복

 

- 정규표현식에 사용되는 문자들

표현 의미
.(Dot) 모든 문자 하나
^(Caret) 문자열의 시작
$ 문자열의 끝
[] []괄호에 있는 문자 하나, [akz]이면 a 또는 k 또는 z
[^ ] []괄호에 있는 문자 이외의 문자 하나. [^ab]이면 a와 b를 제외한 문자 하나
* 0번 이상 반복, {0,}와 동일
+ 1번 이상 반복, {1,}와 동일
? 0번 또는 1번 반복, {0,1}과 동일
{n} n번 반복
{m.n} 최소 m번에서 최대 n번까지 반복
| A|B이면 A 또는 B
[a-z] a에서 z까지 임의의 문자, 즉 영문 소문자 한 개
\d 숫자 한 개, [0-9]와 동일
\w 영문, 숫자 또는 밑줄(_) 한 개, [0-9a-zA-Z_]와 동일

 

출처: 한빛미디어, Django로 배우는 쉽고 빠른 웹 개발 파이썬 웹 프로그래밍

#models.py
from django.db import models


# Create your models here.
class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField('Author')
    publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE)
    publication_date = models.DateField()

    def __str__(self):
        return self.title


class Author(models.Model):
    name = models.CharField(max_length=50)
    salutation = models.CharField(max_length=500)
    email = models.EmailField()

    def __str__(self):
        return self.name


class Publisher(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=100)
    website = models.URLField()

    def __str__(self):
        return self.name

- Book 테이블 생성

컬럼:title, authors, publisher, publication_date

authors는 Book과 Author 테이블이 다대다 관계이므로 ManyToManyField를 사용했고 publisher 컬럼은 Publisher과 Book 테이블이 외래키 관계이기 때문에 ForeignKey를 사용하여 관계를 정의하여 주고 on_delete=model.CASCADE 파라미터를 통해 외래키 관련 레코드가 사라질 경우 해당 외래키와 관련된 레코드들이 지워지는 설정으로 데이터베이스 무결성을 지키기 위함이다.

 

- Author 테이블 생성

컬럼: name, salutation, email

 

- Publisher 테이블 생성

컬럼: name, address, website

 

__str__ 메소드는 admin 페이지에서 해당 레코드가 어떻게 보여질지를 설정할 수 있는 함수이다.

 

- Admin 페이지에 모델 등록하기 및 Admin 페이지 커스텀 하기

from django.contrib import admin
from polls.models import Question, Choice

# Choice 모델을 테이블 형식으로 Inline 생성
# 이것은 Question 모델을 추가할 때 Choice 모델을 같이 보기 위해 사용됨
# extra 2개씩 추가로 보여줌
class ChoiceInline(admin.TabularInline):
    model = Choice
    extra = 2


class QuestionAdmin(admin.ModelAdmin):
    # 필드를 분리하여 보여주기
    # 필드를 설명하는 제목, 필드명, 적용할 옵션
    # collapse: 필드내용 Hide/Show 기능 추가
    # fields = ['pub_date', 'question_text'] -> 등록 페이지에서 컬럼 순서 변경
    fieldsets = [
        ('Question Statement', {'fields':['question_text']}),
        ('Date Information', {'fields': ['pub_date'], 'classes': ['collapse']}),

    ]
    # 같이 볼 모델 클래스
    inlines = [ChoiceInline]
    # admin 페이지에서 보여질 테이블 컬럼
    list_display = ('question_text', 'pub_date')
    # 필터 위젯 추가
    list_filter = ['pub_date']
    # 검색 박스 표시
    search_fields = ['question_text']

# admin 사이트에 모델 등록
admin.site.register(Question, QuestionAdmin)
admin.site.register(Choice)

- 결과 화면

파이썬 웹 프레임워크 중에 가장 많이 사용되고 있으며, 2003년 로렌스 저널 - 월드 신문을 만들던 웹 개발팀의 내부 프로젝트 시작, 2005년 오픈소스 프로젝트로 공개되었다. 구글의 앱 엔진에서 장고를 사용하면서 많은 사람들이 사용하게 되었고, 현재는 파이썬의 대표적인 웹 프레임워크로 자리매김 하였다.

 

- Django의 특징

  • MVC 패턴 기반 MVT : MVC(Model- View - Controller)를 장고에서는 View를 Template, Controller를 View라고 한다. 

 

  • 객체 관계 매핑 : 장고의 객체 관계 매핑(ORM: Object Relation Mapping)은 데이터베이스 시스템과 모델이라는 파이썬 클래스를 연결시키는 다리와 같은 역할을 합니다. SQL 문장을 사용하지 않고도 테이블을 조작할 수 있습니다. 이미 구축한 데이터베이스 시스템을 다른 데이터베이스로 변경하는 경우에도 설정을 조금만 변경하면 가능하다.

 

  • 자동으로 구성되는 관리자 화면: 장고는 프로젝트를 시작하는 시점에 기본 기능으로 관리자 화면을 제공한다. 개발자가 별도로 관리 기능을 개발할 필요가 없다.

 

  • 우아한 URL 설계: 장고에서는 우아한 URL 방식을 채택하여 URL을 직관적이고 쉽게 표현할 수 있다. 또한 정규 표현식을 사용하여 복잡한 URL도 표현 가능하고, 각 URL 형태를 파이썬 함수에 1:1로 연결하도록 되어있어 개발이 편리하다.

 

  • 자체 템플릿 시스템: 내부적으로 확장이 가능하고 디자인이 쉬운 강력한 템플릿 시스템을 가지고 있다. 화면 디자인과 로직에 대한 코딩을 분리하여 독립적으로 개발이 가능하다. 장고 템플릿 시스템은 HTML과 같은 텍스트형 언어를 쉽게 다룰 수 있도록 개발되었다.

 

  • 캐시 시스템: 캐시 시스템을 이용하여 자주 이용되는 내용을 저장해 두었다가 재사용하면 성능을 높일 수 있다. 캐시용 페이지를 메모리, 데이터베이스 내부, 파일 시스템 중 아무 곳에나 저장할 수 있다. 또한 캐시 단위를 페이지에서부터 사이트 전체 또는 특정 뷰의 결과, 템플릿의 일부 영역만을 지정하여 저장할 수 있다.

 

  • 다국어 지원: 동일한 소스코드를 가지고 다른 나라에서도 사용할 수 있도록 다국어 환경을 제공합니다.

 

  • 풍부한 개발 환경: 테스트용 서버등 개발에 도움이 될 수 있는 여러 가지 기능을 제공합니다.

 

  • 소스 변경사항 자동 반영: 개발 중 *.py 파일의 변경 여부를 감지하게 되면 실행 파일에 변경 내역을 바로 반영해준다. 웹 서버를 다시 시작할 필요 없이 자동으로 새파운 파일이 반영됩니다.

 

출처: 한빛미디어, Django로 배우는 쉽고 빠른 웹 개발 파이썬 웹 프로그래밍

파이썬에는 WSGI(Web Server Gateway Interface)규격이 정의되어 있다. 파이썬 애플리케이션은 이 규격을 준수해야한다.

WSGI는 웹 서버와 웹 애플리케이션을 연결해주는 규격으로, 장고와 같은 파이썬 웹 프레임워크를 개발하거나, 이런 웹 프레임워크를 아파치와 같은 웹 서버와 연동할 때 사용한다. 파이썬 표준 라이브러리에는 과거 CGI 규격을 위한 cgi 모듈과 개선된 WSGI 규격을 구현하기 위한 WSGI 규격을 구현하기 위한 wsgiref 모듈이 같이 존재한다.

 

- WSGI 개요

CGI의 단점인 요청이 들어올 때마다 처리를 위한 프로세스가 생성되는 방식을 해결하고, 파이썬 언어로 애플리케이션을 좀 더 쉽게 작성할 수 있도록 웹 서버와 웹 애플리케이션 간에 연동 규격을 정의한 것이 WSGI 규격이다.

 

그렇기 때문에 파이썬에서는 WSGI 규격를 준수한다면 어떤 웹 서버에서도 파이썬 애플리케이션을 실행할 수 있다. 예를 들면 장고로 웹 애플리케이션을 작성하면 Apache, Nginx 웹 서버에서도 실행할 수 있다. 이때 유의해야 될 점은 Apache나 Nginx는 일반 범용 웹 서버로, WSGI 처리 기능이 없다는 것이다. 그렇기 때문에 이런 웹 서버와 파이썬 웹 애플리케이션 중간에서 WSGI 통신 규격을 처리해주는 것이 mod_wsgi, uWSGI, Gunicorn과 같은 WSGI서버이다.

 

 

출처: 한빛미디어, Django로 배우는 쉽고 빠른 웹 개발 파이썬 웹 프로그래밍

 

초창기 웹 서버는 정적 페이들을 보여주는 것이 주된 역할이였지만, 점차 동적 페이지에 대한 요구사항이 생기고, 필요한 데이터를 저장하고 꺼내오는 등의 데이터베이스 처리에 대한 요구가 많아짐에 따라 웹 서버와는 다른 별도의 프로그램이 필요하게 되었다. 이러한 별도의 프로그램과 웹 서버 사이에 정보를 주고받는 규칙을 정의한 것이 바로 CGI 이다.

 

- CGI 방식의 단점

CGI 방식의 근본적인 문제점은 각각의 클라이언트 요청에 대하여 독립적인 별도의 프로세스가 생성된다는 것이다. 요청이 많아질수록 프로세스가 많아지고, 프로세스가 많아질수록 빌{적으로 프로세스가 점유하는 메모리 요구랑도 커져서 시스템에 많은 부하를 주는 요인이 된다. 현재는 CGI 방식을 거의 사용하지 않고 , 이러한 단점을 해결하기 위한 대안책으로 여러가지 기술이 등장했다.

 

- CGI 방식의 대안 기술

CGI 방식의 대한 기술 중 하나는 별도의 애플리케이션(CGI 프로그램과 같은 역할을 하는 프로그램)을 PHP 등의 스크립트 언어로 작성, 스트립트를 처리하는 스크립트 엔진(인터프리터)을 웹 서버에 내장시켜 별도의 프로세스를 기동시키는 오버헤드를 줄이는 방식으로 파이썬에서는 예전의 mod_python 모듈은 더 이상 사용하지 않고, 현재는 mod_wsgi 모듈을 사용

 

또 다른 하나는 애플리케이션을 처리하는 프로세스를 미리 데몬으로 가동시켜 놓은 후, 웹 서버의 요청을 데몬에서 처리하는 것이다. 이것 또한 프로세스 생성 부하를 줄일 수 있는 방법이다. 파이썬의 경우에는 데몬 방식에도 mod_wsgi 모듈을 사용한다. mod_wsgi 모듈을 앞에서처럼 웹 서버 내장 방식으로도 실행이 가능하고, 별도의 데몬 방식으로도 실행 가능하다.

 

CGI 애플리케이션을 별도의 데몬으로 처리하는 방식이 발전하여 스레드 처리 보강, 객체 지향 기술 반영으로 애플리케이션 전용 데몬인 애플리케이션 서버 방식으로 발전했다. 가장 많이 사용되고 있는 JSP(Java Server Page), ASP(Active Server Page) 기술에서 애플리케이션 서버 방식을 사용중이다.

 

파이썬에서 웹 서버 연동용으로 사용하는 mod_wsgi, uwsgi, gunicorn 프로그램들이, 웹 서버 프로그램인 httpd, nginx와는 별개의 애플리케이션 전용 데몬으로 동작한다는 점에서 웹 애플이케이션 서버라고 할 수 있다.

 

출처: 한빛미디어, Django로 배우는 쉽고 빠른 웹 개발 파이썬 웹 프로그래밍

구분 역할 프로그램 명
웹 서버 웹 클라이언트의 요청을 받아서 요청을 처리하고, 그 결과를 웹 클라이언트에게 응답합니다. 
주로 정적 페이지인 HTML, 이미지, CSS, 자바스크립트 파일을 웹 클라이언트에 제공할 때 웹 서버를 사용합니다. 만약 동적 페이지 처리가 필요하다면 웹 애플리케이션 서버에 처리를 넘깁니다.
Apache httpd, Nginx, lighttpd,IIS 등
웹 애플리케이션 서버 웹 서버로부터 동적 페이지 요청을 받아서 요청을 처리하고, 그 결과를 웹 서버로 반환합니다.
주로 동적 페이지 생성을 위한 프로그램 실행과 데이터베이스 연동 기능을 처리합니다.
Apache Tomecat, JBoss, WebLogic, Jeus, mod_wsgi,
uWSGI, Gunicorn 등

정적 페이지:

누가, 언제 요구하더라고 항상 같은 내용을 표시하는 웹 페이지를 말한다. 웹 서비스 제공자가 사전에 준비하여 서버 측에 배치하여 놓고, 동일한 리소스의 요청에 대해서는 항상 동일한 내용의 페이지를 반환한다. 주로 HTML, 자바스크립트, CSS, 이미지만으로 이루어진 페이지가 해당된다.

 

동적 페이지:

동일한 리소스 요청이라도 누가, 언제, 어떻게 요구했는지에 따라 각각 다른 내용이 반환되는 페이지를 말한다.

 

출처: 한빛미디어, Django로 배우는 쉽고 빠른 웹 개발 파이썬 웹 프로그래밍

'Django' 카테고리의 다른 글

6. Django 웹 프레임워크  (0) 2021.04.07
5. WSGI (Web Server Gateway Interface)  (0) 2021.04.07
4. CGI (Common Gateway Interface)  (0) 2021.04.07
2. URL 설계  (0) 2021.04.07
1. HTTP (구조, 메소드, 상태코드)  (0) 2021.04.07

URL은 보통 다음과 같이 구성됩니다.

http://www.example.com:80/services?category=2&kind=patents#n10 

  • URL 스킴: URL에 사용된 프로토콜 ex) http
  • 호스트명: 웹 서버의 호스트명, 도메인명 또는 IP 주소 ex) www.example.com
  • 포트번호: 웹 서버 내의 서비스 포트번호. 생략 시 디폴트 포트번호로 http는 80로, https는 443 ex) 80
  • 경로: 파일이나 애플리케이션 경로 ex)service
  • 쿼리스트링: 질의 문자열로, 앰퍼샌드(&)로 구분된 이름=값 쌍 형식 ex) category=2&kind=patents
  • 프라그먼트: 문서 내의 앵커 등 조각을 지정 ex)#n10

출처: 한빛미디어, Django로 배우는 쉽고 빠른 웹 개발 파이썬 웹 프로그래밍

+ Recent posts