Language/Python [Pyhton] Django 결과보기/404오류/템플릿 상속/네비게이션바
  • 728x90
    반응형

     

     

     

    여론조사 결과 보기2

    views.py 파일의 results 함수 수정

    def results(request, area):
        candidates = Candidate.objects.filter(area = area)
        context = {'canidates':candidates, 'area': area}
        polls = Poll.objects.filter(area = area)
        poll_results = []
        for poll in polls:
            result = {}
            result['start_date'] = poll.start_date
            result['end_date'] = poll.end_date
    
            poll_results.append(result)
        context = {'candidates':candidates, 'area': area, 'poll_results': poll_results}
        return render(request, 'elections/result.html', context)

     

    result.html 파일 수정

    <!-- C:\Code\mysite\elections\templates\elections\result.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>{{area}} 여론조사 결과</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
      <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    </head>
    <body>
    <div class="container">
    <h1>{{area}} 여론조사 결과</h1>
    <br>
    <table class="table table-striped">
        <thead>
        <tr>
            <td><B>기간</B></td>
            {% for candidate in candidates %}
            <td><B>{{candidate.name}}</B></td>
            {% endfor %}     
        </tr>
        </thead>
        <tbody>
        {% for result in poll_results %}
        <tr>
            <td> {{result.start_date.year}}/{{result.start_date.month}}/{{result.start_date.day}}~{{result.end_date.year}}/{{result.end_date.month}}/{{result.end_date.day}}</td>
            <td> 후보1 지지율</td>
            <td> 후보2 지지율</td>        
        </tr>  
        {% endfor %}  
        <tbody>
    </table>
    </div>
    </body>

     

    새로고침 결과

     

     

     

     

    여론조사 결과 보기3 - Dictionary로 데이터 정리

    views.py 파일의 results 함수 수정

    # C:\Code\mystite\elections\views.py
    
    from django.db.models import Sum
    
    # 기존 코드 유지 
    
    def results(request, area):
        candidates = Candidate.objects.filter(area = area)
    
        polls = Poll.objects.filter(area = area)
        poll_results = []
        for poll in polls:
            result = {}
            result['start_date'] = poll.start_date
            result['end_date'] = poll.end_date
    
            # poll.id에 해당하는 전체 투표수 
            total_votes = Choice.objects.filter(poll_id = poll.id).aggregate(Sum('votes'))
            result['total_votes'] = total_votes['votes__sum']
    
            rates = []    # 지지율 
            for candidate in candidates:
                # choice가 하나도 없는 경우 - 예외처리로 0을 append
                try:
                    choice = Choice.objects.get(poll = poll, candidate = candidate)
                    rates.append(round(choice.votes * 100/result['total_votes'], 1))
                except:
                    rates.append(0)
            result['rates'] = rates
            poll_results.append(result)
    
        context = {'candidates':candidates, 'area': area, 'poll_results': poll_results}
        return render(request, 'elections/result.html', context)

     

    result.html 수정

    <!-- C:\Code\mysite\elections\templates\elections\result.html -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>{{area}} 여론조사 결과</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
      <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    </head>
    <body>
    <div class="container">
    <h1>{{area}} 여론조사 결과</h1>
    <br>
    <table class="table table-striped">
        <thead>
        <tr>
            <td><B>기간</B></td>
            {% for candidate in candidates %}
            <td><B>{{candidate.name}}</B></td>
            {% endfor %}     
        </tr>
        </thead>
        <tbody>
        {% for result in poll_results %}
        <tr>
            <td> {{result.start_date.year}}/{{result.start_date.month}}/{{result.start_date.day}}~{{result.end_date.year}}/{{result.end_date.month}}/{{result.end_date.day}}
            </td>
            {% for rate in result.rates %}
            <td> {{rate}}%</td>
            {% endfor %}
        </tr>  
        {% endfor %}  
        <tbody>
    </table>
    </div>
    </body>

     

    Poll 추가 후 새로고침 결과

     

     

     

     

    404 오류

    📌 존재하지 않는 페이지에 대한 요청이 들어 왔을 경우 처리 방법

     

    후보 상세 페이지를 추가 한다.

     

    urls.py 추가

    from django.conf.urls import url
    from . import views
    
    urlpatterns = [
        url(r'^$', views.index),
        url(r'^areas/(?P<area>[가-힣]+)/$', views.areas),
        url(r'^areas/(?P<area>[가-힣]+)/results$', views.results),
        url(r'^polls/(?P<poll_id>\d+)/$', views.polls), #이 url에 대한 요청을 views.polls가 처리하게 만든다.
        url(r'^candidates/(?P<name>[가-힣]+)/$', views.candidates),
    ]

     

    여러가지 방법으로 예외 처리하기

     

    • Basic
    # C:\Code\mysite\elections\views.py
    
    # 기존 코드 유지
    
    def candidates(request, name):
        candidate = Candidate.objects.get(name = name)
        return HttpResponse(candidate.name)

     

     

    없는 페이지 접속결과

     

     

    • 예외 처리로 object가 없는 경우 HttpResponseNotFound 처리하기
    # C:\Code\mysite\elections\views.py
    
    from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound  # 추가
    
    # 기존 코드 유지
    
    def candidates(request, name):
        try:
            candidate = Candidate.objects.get(name = name)
        except:
            return HttpResponseNotFound("없는 페이지 입니다.")
        return HttpResponse(candidate.name)

     

    없는 페이지 접속결과

     

     

    • 예외 처리로 url이 없는 경우와, object가 없는 경우를 함께 처리하기
    # C:\Code\mysite\elections\views.py
    
    from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound, Http404 # 추가
    
    # 기존 코드 유지
    
    def candidates(request, name):
        try:
            candidate = Candidate.objects.get(name = name)
        except:
            raise Http404
        return HttpResponse(candidate.name)

     

    없는 페이지 접속결과

     

     

    • 예외 처리없이 url이 없는 경우와, object가 없는 경우를 함께 처리하기
    # C:\Code\mysite\elections\views.py
    
    from django.shortcuts import render, get_object_or_404
    
    # 기존 코드 유지
    
    def candidates(request, name):
        candidate = get_object_or_404(Candidate, name = name)
    
        return HttpResponse(candidate.name)

     

    없는 페이지 접속결과

     

     

     

     

     

    404페이지 변경하기

    • 디버그 설정과 디렉토리 설정 바꿔주기

     

     

    • 404파일 만들어주기

    맨 상위 폴더에서 templates폴더를 생성 후 404.html을 다음과 같이 작성한다.

     

     

    없는 페이지 접속결과

     

     

     

     

    템플릿 상속

    • layout.html 설정

    templates < elections 파일 내부에 layout.html 파일을 아래와 같이 작성한다.

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>{% block title %}{% endblock %}</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
      <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    </head>
    <body>
    {% block content %}{% endblock %}
    </body>
    </html>

     

    • 각 html파일에 layout.html 상속받기

    index.html

    • <!DOCTYPE html> 부터 </head>까지 삭제
    • <body>, </body>, </html> 태그 제거
    <!-- mysite\elections\templates\elections\index.html -->
    {% extends "elections/layout.html" %}
    
    {% block title %}
    선거 후보
    {% endblock %}
    
    {% block content %}
    <div class="container">
      <table class="table table-striped">
            <thead>
            <tr>
                <td><B>이름</B></td>
                <td><B>소개</B></td>
                <td><B>출마지역</B></td>
                <td><B>기호</B></td>
            </tr>
            </thead>
            <!-- 이 부분이 수정됨 -->
            <tbody>
            {% for candidate in candidates %}
            <tr>
                <td>{{candidate.name}}</td>
                <td>{{candidate.introduction}}</td>
                <td><a href = "areas/{{candidate.area}}/">
                {{candidate.area}}</a></td>
                <td>기호{{candidate.party_number}}번</td>
            </tr>
            {% endfor %}
            <!-- 여기까지 -->
            <tbody>
        </table>
    {% endblock %}

     

    area.html

    • <!DPCTYPE html> 부터</head>까지 삭제
    • <body> ,</body>,</html>태그 제거
    <!-- C:\Code\mysite\templates\elections\area.html -->
    {% extends "elections/layout.html" %}
    
    {% block title %}
    {{area}}
    {% endblock %}
    
    {% block content %}
    <div class="container">
    <h1>{{area}}</h1>
    <br>
    {% if poll %}
      <table class="table table-striped">
          <thead>
          <tr>
              <td><B>이름</B></td>
              <td><B>소개</B></td>
              <td><B>기호</B></td>
              <td><B>지지하기</B></td>
          </tr>
          </thead>
          <tbody>
          {% for candidate in candidates %}
          <tr>
              <td> {{candidate.name}}</td>
              <td> {{candidate.introduction}}</td>
              <td> 기호{{candidate.party_number}}번 </td>
              <td>
                  <form action = "/polls/{{poll.id}}/" method = "post">
                  {% csrf_token %}
                      <button name="choice" value="{{candidate.id}}">선택</button>
                  </form>
              </td>
          </tr>
          {% endfor %}
          </tbody>
      </table>
    {% else %}
      투표가 없습니다.
    {% endif %}
    </div>
    {% endblock %}

     

    result.html

    • <!DPCTYPE html> 부터</head>까지 삭제
    • <body> ,</body>, </html>태그 제거
    <!-- C:\Code\mysite\elections\templates\elections\result.html -->
    {% extends "elections/layout.html" %}
    
    {% block title %}
    {{area}} 여론조사 결과 
    {% endblock %}
    
    {% block content %}
    <div class="container">
    <h1>{{area}} 여론조사 결과</h1>
    <br>
    <table class="table table-striped">
        <thead>
        <tr>
            <td><B>기간</B></td>
            {% for candidate in candidates %}
            <td><B>{{candidate.name}}</B></td>
            {% endfor %}
        </tr>
        </thead>
        <tbody>
        {% for result in poll_results %}
        <tr>
            <td> {{result.start_date.year}}/{{result.start_date.month}}/{{result.start_date.day}}~{{result.end_date.year}}/{{result.end_date.month}}/{{result.end_date.day}} </td>
            {% for rate in result.rates %}
            <td> {{rate}}%</td>
            {% endfor %}
        </tr>    
        <tbody>
        {% endfor %}
    </table>
    </div>
    {% endblock %}

     

     

    네비게이션바 추가하기

    📌 templates/elections/layout.html 파일에 네비게이션바 코드 추가

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>{% block title %}{% endblock %}</title>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
      <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
    </head>
    <body>
    <nav class="navbar navbar-default">
      <div class="container-fluid">
        <div class="navbar-header">
          <a class="navbar-brand" href="#">사이트명</a>
        </div>
    </nav>
    {% block content %}{% endblock %}
    </body>
    </html>

     

    네비게이션바 코드 추가 후 새로고침 결과 (모든 페이지에 공통적으로 생성된다.)

     

     

    • layout 추가하기

    아래와 같이 home 의 경로를 정해주면 모든 페이지에서 사이트명을 누르면 첫 페이지로 되돌아간다.

    <body>
    <nav class="navbar navbar-default">
      <div class="container-fluid">
        <div class="navbar-header">
          <a class="navbar-brand" href="{% url 'elections:home' %}">사이트명</a>
        </div>
    </nav>

     

    • url 설정
    # C:\Code\mysite\elections\urls.py
    
    # 기존 코드 유지
    
    app_name = 'elections'
    urlpatterns = [
        url(r'^$', views.index, name = 'home'),
        # 기존 코드 유지
    ]

     

     

     

     

    728x90
    반응형
상단으로