Django tutorial 2.

Sinjae Lee·2021년 6월 16일
0

해당 페이지는 part2~4의 내용을 포함하고 있습니다.

0. Database setup

일단 settings.py 를 확인해보자

Database 는 기본적으로 default sqlite 로 설정되어있다.
만약 다른 database를 사용한다면
ENGINE : 'django.db.backends.sqlite3', 'django.db.backends.postgresql',
'django.db.backends.mysql',
'django.db.backends.oracle'
위의 값으로 수정해서 적용해줘야한다.

TIME_ZONE

해당 그림의 TIME_ZONE = 'UTC' 라고 되어있을것이다.
우리는 한국인이니까 Asia/seoul로 바꿔주자

INSTALLED_APPS

이전 tutorial1에서 잠깐 살펴본 installed apps 를 보자

기본적으로는, INSTALLED_APPS는 Django와 함께 딸려오는 다음의 앱들을 포함합니다.
django.contrib.admin – 관리용 사이트. 곧 사용하게 될 겁니다.
django.contrib.auth – 인증 시스템.
django.contrib.contenttypes – 컨텐츠 타입을 위한 프레임워크.
django.contrib.sessions – 세션 프레임워크.
django.contrib.messages – 메세징 프레임워크.
django.contrib.staticfiles – 정적 파일을 관리하는 프레임워크.

1. VIEWS 만들기

views?
- django 가 특정 기능과 template 를 제공하는 웹페이지
예를들어 해당 velog 에는

  • 메인 홈페이지
  • detail 세부 목차 페이지
  • 날짜별 페이지
  • 댓글 기능 등
    과 같은 views 페이지를 가질 수 있다.

우리는 아래와 같은 4개의 페이지를 만들어 볼것이다.

새로운 views 내용 작성

views 작성해줬으면 urls 연결

공식문서 설명이다
When somebody requests a page from your website – say, “/polls/34/”, Django will load the mysite.urls Python module because it’s pointed to by the ROOT_URLCONF setting.
-> browser 에서 "/polls/34/" 가 request 되면
It finds the variable named urlpatterns and traverses the patterns in order. After finding the match at 'polls/', it strips off the matching text ("polls/") and sends the remaining text – "34/" – to the ‘polls.urls’ URLconf for further processing.
-> urlpatterns 에서"polls/" 부분을 찾은 뒤 그 뒤의 text인 "34/" 를 보낸다
There it matches '<int:question_id>/', resulting in a call to the detail() view like so:

-> 이 "34/"는 urls.py에서 path ('<int:question_id>/', views.detail) 부분 이기에 해당 view를 호출한다

polls/1 호출
polls/1/results 호출
polls/1/vote 호출

이런 말이다

view 가 작동하기 위해서는
위의 그림 처럼 request 내용이 담기 HttpResponse 객체를 반환하거나 Http404 같은 exception이 발생해야합니다.

HttpResponse
HttpRequest 객체를 받아서 HttpResponse 객체를 반환하는데, HttpResponse는 django가 해주지 않는다 우리가 직접 만들어야한다 ㅎㅎ

우선 polls dir 에 template dir 를 만들어 준뒤 index.html 파일을 만든 후

from django.http import HttpResponse
from django.template import loader

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    template = loader.get_template('polls/index.html')
    context = {
        'latest_question_list': latest_question_list,
    }
    return HttpResponse(template.render(context, request))

template> index.html 에 연결하는 코드를 작성해준다

get_template 이 어떤 method인지 확인하고자 한다면 alt키로 확인해주자 get_template(template_name)으로 template을 불러 온다는 것을 알 수 있다.

template을 불러온 후 context를 전달한다.
근데 이렇게 context 를 통해서 HttpResponse 에 대한 부분은 자주 작성하는 부분이다.
이런 자주 쓰는 코드 같은 것들은 간단하게 만들고 싶다. 그래서 django에도 render 모듈이 있다.

(항상 django 페이지에서 직접 모듈 , 함수 인자들을 확인해주자)
이렇게 render 를 써주면

from django.shortcuts import render

from .models import Question


def index(request):
    latest_question_list = Question.objects.order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

코드가 요렇게 깔끔해진다. (근데 요새 render 는 잘 안쓴다고 하니 참고만 하자)

이제 HttpResponse는 어느 정도 했다 근데 exception 이 발생할때의 코드를 작성해주자

먼저 templates> polls> detail.html 을 작성해준 후

{{question}}

을 입력해두고
views.py 로 돌아와서

from django.shortcuts import get_object_or_404, render

from .models import Question
# ...
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

를 작성해주자

get_object_or_404 는 obhect 가 존재하지 않는다면 Http404를 발생시킨다.
해당 함수는 get 함수 즉 dict 값인데 만약 list 로 return 한다면 get_list_or_404도 있다.


그렇다고 한다.

근데 실제 django 프로젝트를 시작하면 polls같은 앱이 여러개일텐데 이들 사이에 URL name 을 어떻게 다르게 할까? urlconf 에 namespaces 를 추가 한다고 한다.
urls.py 에서

from django.urls import path

from . import views

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

app_name = 'polls' 추가 해주고

url 'polls:detail' 로 수정해준다.

2. 투표 form 설정

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse

from .models import Choice, 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'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

위 코드는 이 튜토리얼에서 아직 다루지 않은 몇 가지를 포함하고 있습니다:

  • request.POST 는 키로 전송된 자료에 접근할 수 있도록 해주는 사전과 같은 객체, request.POST['choice'] 는 선택된 설문의 ID를 문자열로 반환합니다. request.POST 의 값은 항상 문자열들입니다.

  • Django는 같은 방법으로 GET 자료에 접근하기 위해 request.GET 를 제공합니다 – 그러나 POST 요청을 통해서만 자료가 수정되게하기 위해서, 명시적으로 코드에 request.POST 를 사용하고 있습니다.

  • 만약 POST 자료에 choice 가 없으면, request.POST['choice'] 는 KeyError 가 일어납니다. 위의 코드는 KeyError 를 체크하고, choice가 주어지지 않은 경우에는 에러 메시지와 함께 설문조사 폼을 다시보여줍니다.

  • 설문지의 수가 증가한 이후에, 코드는 일반 HttpResponse 가 아닌 HttpResponseRedirect 를 반환하고, HttpResponseRedirect 는 하나의 인수를 받습니다: 그 인수는 사용자가 재전송될 URL 입니다. (이 경우에 우리가 URL을 어떻게 구성하는지 다음 항목을 보세요).

  • As the Python comment above points out, you should always return an HttpResponseRedirect after successfully dealing with POST data. This tip isn’t specific to Django; it’s good Web development practice in general. -> POST data 처리 한 후에 HttpResponseRedirect 를 return 해야한다!

    우리는 이 예제에서 HttpResponseRedirect 생성자 안에서 reverse() 함수를 사용하고 있습니다. 이 함수는 뷰 함수에서 URL을 하드코딩하지 않도록 도와줍니다. 제어를 전달하기 원하는 뷰의 이름을, URL패턴의 변수부분을 조합해서 해당 뷰를 가리킵니다. 여기서 우리는 튜토리얼 3장에서 설정했던 URLconf를 사용하였으며, 이 reverse() 호출은 아래와 같은 문자열을 반환할 것입니다.

profile
Back-end developer

0개의 댓글