Django 공식 홈페이지 최신 Tutorial 찌꺼기 뒤집기 - Part 4

10819 단어
이전 섹션: Django 홈페이지 최신 Tutorial 찌꺼기 뒤집기 - Part 3
Tutorial 3에 이어서 우리는 이 투표의 웹 응용 프로그램을 계속 개발할 것이다. 본 장은 간단한 폼 처리와 코드 최적화에 주목할 것이다.
간단한 폼을 작성하다
이전 강좌에서 작성한 투표 상세 페이지의 템플릿("polls/detail.html")을 업데이트하여 HTML 요소를 포함시킵니다.
polls/templates/polls/detail.html

{% if error_message %}

{{ error_message }}

{% endif %} {% csrf_token %} {% for choice in question.choice_set.all %}
{% endfor %}

간략한 설명:
  • detail 웹 템플릿에Question에 대응하는 모든 Choice에 선택 단추를 추가했습니다.각 라디오 버튼의 속성은 해당 각 Choice의 ID입니다.각 라디오 버튼의 valuename입니다.이것은 누군가가 라디오 단추를 선택하고 폼을 제출할 때 POST 데이터"choice"를 보내는데 이 중 #은 선택한 Choice의 ID이다.HTML 양식의 기본 개념입니다.
  • 우리는 폼의 choice=#action로 설정하고 {% url 'polls:vote' question.id %}를 설정한다.method="post"(상대적으로method="post")를 사용하는 것은 매우 중요하다. 왜냐하면 이 폼을 제출하는 행위는 서버 측의 데이터를 바꾸기 때문이다.언제든지 서버 측 데이터를 바꾸는 폼을 만들어야 할 때 method="get" 을 사용하십시오.이것은 Django의 특정한 기교가 아니다.이것은 우수한 사이트 개발 실천이다.
  • method="post"forloop.counter 라벨이 순환한 횟수를 나타낸다.
  • POST 폼을 만들었기 때문에 크로스 사이트 위조 요청(csrf)의 공격을 걱정합니다.다행히도, 우리는 너무 걱정할 필요가 없다. 왜냐하면, Django는 스스로 간단하고 사용하기 쉬운 시스템을 가지고 있기 때문이다.요컨대, 목표 URLs에 제출된 모든 POST 폼은 for 템플릿 탭을 설정해야 한다.

  • Now, let’s create a Django view that handles the submitted data and does something with it. Remember, in Tutorial 3, we created a URLconf for the polls application that includes this line:
    이제 제출한 데이터를 처리하기 위해 Django 보기를 만듭니다.Tutorial 3에서는 투표 애플리케이션을 위한 URLconf가 만들어졌습니다. 이 행은 다음과 같습니다.
    polls/urls.py
    
    path('/vote/', views.vote, name='vote'),
    

    We also created a dummy implementation of the {% csrf_token %} function. Let’s create a real version. Add the following to vote() :
    우리도 실제 기능이 없는 polls/views.py 함수를 만들었다.이제 실제 버전을 만들어 봅시다.다음 코드를 polls/views에 추가합니다.py:
    polls/views.py
    
    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):
            #     question    
            return render(request, 'polls/detail.html', {
                'question': question,
                'error_message': "You didn't select a choice.",
            })
        else:
            selected_choice.votes += 1
            selected_choice.save()
            #     POST         HttpResponseRedirect  ,
            #                         .
            return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
    

    이 코드에는 자습서에서 언급하지 않은 몇 가지 지식이 있습니다.
  • vote()는 키워드의 이름을 통해 제출한 데이터를 얻을 수 있는 사전과 유사한 대상이다.이 예에서 request.POST는 선택한 Choice의 ID를 문자열로 반환합니다.request.POST['choice']의 값은 항상 문자열입니다.Django는 GET 데이터에 접근하기 위해 같은 방식으로 request.POST 제공하지만, 코드에서 request.GET 을 현저하게 사용해서 POST 호출을 통해서만 데이터가 바뀔 수 있도록 합니다.
  • POST 데이터에 제공되지 않으면request.POST request.POST['choice'] 1개choice를 유발한다.위의 코드 검사 KeyError 를 주지 않으면 Question 폼과 오류 정보를 다시 표시합니다.
  • 초이스의 득표수를 늘린 후 코드는 상용KeyError이 아닌 choice로 되돌아왔다.HttpResponseRedirect 매개 변수만 수신합니다: 사용자가 방향을 바꿀 URL입니다. (계속 보십시오. 이 예의 URL을 어떻게 구성하는지 설명하겠습니다.)위의 Python 주석에서 지적한 바와 같이, POST 데이터를 성공적으로 처리한 후에 항상 HttpResponse 하나를 되돌려야 한다.이 힌트는 Django의 특유의 것이 아니다.이것은 단지 좋은 웹 개발 실천일 뿐이다.
  • 이 예에서 우리는 HttpResponseRedirect의 구조 함수에서 HttpResponseRedirect 함수를 사용한다.이 함수는 보기 함수에서 URL을 하드코딩하는 것을 피합니다.이것은 우리가 이동하고자 하는 보기의 이름과 이 보기에 대응하는 URL 모드에서 이 보기에 제공할 파라미터를 보여 주어야 합니다.이 경우 Tutorial 3에 설정된 URLconf를 사용하면 이 HttpResponseRedirect 호출은 문자열을 되돌려줍니다.
  • '/polls/3/results/'
    

    그중 3은 reverse()의 값이다.리디렉션된 URL은 보기reverse()를 호출하여 최종 페이지를 표시합니다.
    Tutorial 3에서 말한 바와 같이 question.id'results' 대상이다.request 대상에 대한 자세한 내용은 Request and response documentation을 참조하십시오.
    Question에 대한 투표가 진행되면 HttpRequest 보기에서 Question의 결과 인터페이스로 리셋을 요청합니다.이 뷰를 작성해 보겠습니다.
    polls/views.py
    
    from django.shortcuts import get_object_or_404, render
    
    def results(request, question_id):
        question = get_object_or_404(Question, pk=question_id)
        return render(request, 'polls/results.html', {'question': question})
    

    이는 Tutorial 3의 HttpRequest 뷰와 거의 동일합니다.유일한 차이는 템플릿의 이름이다.우리는 잠시 후에 이 불필요한 문제를 해결할 것이다.
    다음은 vote() 템플릿을 생성합니다.
    polls/templates/polls/results.html
    
    

    {{ question.question_text }}

      {% for choice in question.choice_set.all %}
    • {{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}
    • {% endfor %}
    Vote again?

    현재 브라우저에서 detail() 를 방문하여Question에 투표하십시오.투표 결과 페이지를 보고 투표할 때마다 업데이트해야 한다.만약 제출할 때 Choice를 선택하지 않았다면, 잘못된 정보를 보았을 것입니다.
    Note polls/results.html 보기의 코드에 작은 문제가 있습니다.그것은 먼저 데이터베이스에서 /polls/1/ 대상을 얻은 다음에 vote()의 새로운 값을 계산한 다음에 그것을 데이터베이스에 저장한다.만약 사이트의 두 사용자가 완전히 같은 시간에 투표를 시도한다면 오류가 발생할 수 있습니다. selected_choice 는 같은 값을 검색합니다. 42입니다.그리고 두 사용자에 대해 새 값 43을 계산하고 저장하지만 44는 예상 값이다.이것은 경쟁 조건이라고 불린다.관심 있는 경우 F()를 사용하여 경쟁 조건을 피하여 이 문제를 해결하는 방법을 읽을 수 있습니다.
    일반 보기 사용하기: 적은 코드가 더 좋다
    The votes (from Tutorial 3) and votes views are very simple – and, as mentioned above, redundant. The detail() view, which displays a list of polls, is similar. results()(Tutorial 3에서)와 index() 보기는 모두 간단합니다. 그리고 위에서 언급한 바와 같이 불필요한 문제가 존재합니다.폴링 목록detail()을 표시하는 뷰도 비슷합니다.
    이러한 뷰는 URL의 매개 변수에 따라 데이터베이스에서 데이터를 가져오고 템플릿 파일을 로드한 다음 렌더링된 템플릿으로 돌아가는 기본 웹 개발의 일반적인 상황을 반영합니다.이런 상황이 매우 보편적이기 때문에 Django는'generic views(공통 보기)'라는 시스템을 제공하여 편리하게 처리할 수 있다.
    Generic views는 일반적인 패턴을 추상화하여 앱을 작성할 때 파이썬 코드를 작성하지 않아도 된다.
    우리의 투표 애플리케이션을 유니버설 보기 시스템으로 바꾸어 많은 우리의 코드를 삭제할 수 있도록 하자.우리는 단지 다음과 같은 몇 가지 단계를 통해 전환을 완성해야 한다. 우리는 다음과 같다.
  • URLconf 변환
  • 더 이상 필요하지 않은 오래된 코드를 삭제합니다.
  • Django 공통 뷰를 기반으로 한 새로운 뷰를 도입합니다.

  • 자세한 내용은 계속 읽으십시오.
    코드를 왜 재구성해야 합니까?일반적으로, Django 응용 프로그램을 작성할 때, 일반적인 보기가 당신의 문제를 해결할 수 있는지 평가해야 한다. 처음부터 그것을 사용해야 하며, 절반까지 진행되었을 때 코드를 재구성하는 것이 아니라.본 강좌는 지금까지'어려운 방식'으로 보기를 작성하는 데 중점을 두고자 하였으며, 이는 핵심 개념에 중점을 두기 위한 것이다.계산기를 사용하기 전에 기본적인 수학을 알아야 하는 것처럼.
    URLconf 수정
    먼저 URLconfresults()를 열고 다음과 같이 수정합니다.
    polls/urls.py
    
    from django.urls import path
    
    from . import views
    
    app_name = 'polls'
    urlpatterns = [
        path('', views.IndexView.as_view(), name='index'),
        path('/', views.DetailView.as_view(), name='detail'),
        path('/results/', views.ResultsView.as_view(), name='results'),
        path('/vote/', views.vote, name='vote'),
    ]
    

    세 번째와 네 번째가 일치하는 패널 중 index()polls/urls.py로 바뀌었음을 주의하세요.
    뷰 수정
    다음 단계에서, 우리는 낡은 , , results 보기를 삭제하고, Django의 일반적인 보기로 대체할 것입니다.index 파일을 열고 다음과 같이 수정합니다.
    polls/views.py
    
    from django.http import HttpResponseRedirect
    from django.shortcuts import get_object_or_404, render
    from django.urls import reverse
    from django.views import generic
    
    from .models import Choice, Question
    
    
    class IndexView(generic.ListView):
        template_name = 'polls/index.html'
        context_object_name = 'latest_question_list'
    
        def get_queryset(self):
            """    5    question."""
            return Question.objects.order_by('-pub_date')[:5]
    
    
    class DetailView(generic.DetailView):
        model = Question
        template_name = 'polls/detail.html'
    
    
    class ResultsView(generic.DetailView):
        model = Question
        template_name = 'polls/results.html'
    
    
    def vote(request, question_id):
        ... # same as above, no changes needed.
    

    우리는 여기서 두 개의 통용 보기를 사용한다. detailpolls/views.py.이 두 보기는 각각 '하나의 대상 목록 보이기' 와 '특정한 유형의 대상의 상세한 정보 페이지 보이기' 두 가지 개념을 추상화한다.
  • 모든 일반 보기는 어느 모델에 작용할지 알아야 한다.모델 속성에서 제공합니다.
  • ListView는 URL에서 DetailView라는 키 값을 포획하기를 기대하기 때문에 우리는 DetailView에서"pk"polls/urls.py로 바꾸어 일반적인 보기에서 키 값을 찾을 수 있도록 했다.

  • 기본적으로 일반 보기 question_idpk 라는 템플릿을 사용합니다.우리의 예에서, 그것은 DetailView 템플릿을 사용할 것이다./_detail.html 속성은 자동으로 생성된 기본 이름이 아닌 지정한 템플릿 이름을 사용하도록 Django에게 알려주는 데 사용됩니다.우리도 "polls/question_detail.html" 목록 보기 template_name 를 지정했습니다. 리소스 보기와detail 보기가 렌더링할 때 서로 다른 외관을 가지고 있는지 확인합니다. 백엔드가 똑같아도 template_name.
    유사하게results 유니버설 보기 사용명DetailView;우리는 ListView 을 사용하여 /_list.html 기존의 template_name 템플릿을 사용하라고 알려 줍니다.
    이전 강좌에서 템플릿 파일을 제공할 때 ListView 변수와 "polls/index.html" 변수를 포함하는 context를 가지고 있습니다.question에 대해 latest_question_list 변수는 자동으로 제공됩니다. Django의 모델(Question을 사용하기 때문에 Django는context 변수에 적합한 이름을 결정할 수 있습니다.그러나 DetailView에 대해 자동으로 생성된context 변수는question이다.이 행위를 덮어쓰기 위해서, 우리는 ListView 속성을 제공하여, 우리가 사용하고 싶다는 것을 표시합니다 question_list.새 context 변수와 일치하는 템플릿을 바꿀 수 있지만, Django에게 원하는 변수를 사용하라고 직접 알려주면 훨씬 수월합니다.
    서버를 시작하고 일반적인 보기를 기반으로 한 새로운 투표 애플리케이션을 사용하십시오.
    일반 뷰에 대한 자세한 내용은 generic views documentation을 참조하십시오.
    당신이 쓴 폼과 일반적인 보기가 만족스러우면 part 5 of this tutorial을 읽어서 우리의 투표 응용을 어떻게 테스트하는지 알아보십시오.
    다음 섹션: Django 홈페이지 최신 Tutorial 찌꺼기 뒤집기 - Part 5

    좋은 웹페이지 즐겨찾기