Language/Python

[Pyhton] Django 결과보기/404오류/템플릿 상속/네비게이션바

Dexter_- 2017. 8. 16. 10:43
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
반응형