본문 바로가기

파이썬 프로그래밍/Django기초

[django] 장고. dictionary를 사용하여 화면에 지지율 표시하기.

1. views에서 넘겨줄 results함수의 내용 수정하기

코드복사는 아래코드 쓰시면 되고 아래에 코드를 쪼개서 설명 달아놓겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from .models import Candidate, Poll, Choice
import datetime
from django.db.models import Sum
 
# Create your views here.
def index(request):
    candidates = Candidate.objects.all()
    context = {'candidates':candidates}
        #context에 모든 어린이 정보를 저장
    return render(request, 'elections/index.html', context)
        #context안에 있는 어린이 정보를 index.html로 전달
 
def areas(request, area):
    today = datetime.datetime.now()
    try :
        poll = Poll.objects.get(area = area, start_date__lte = today, end_date__gte=today) # get에 인자로 조건을 전달해줍니다. 
        candidates = Candidate.objects.filter(area = area) # Candidate의 area와 매개변수 area가 같은 객체만 불러오기
    except:
        poll = None
        candidates = None
    context = {'candidates': candidates,
    'area' : area,
    'poll' : poll }
    return render(request, 'elections/area.html', context)
 
def polls(request, poll_id):
    poll = Poll.objects.get(pk = poll_id)#Poll객체를 구분하는 녀석은 poll_id이므로 PK지정
    selection = request.POST['choice']
 
    try:
        #choice모델을 불러와서 1을 증가시킨다 
        choice = Choice.objects.get(poll_id = poll.id, candidate_id = selection)
        choice.votes += 1
        choice.save()
    except:
        #최초로 투표하는 경우, DB에 저장된 Choice객체가 없기 때문에 Choice를 새로 생성합니다
        choice = Choice(poll_id = poll.id, candidate_id = selection, votes = 1)
        choice.save()
 
    #return HttpResponse("finish")
    return HttpResponseRedirect("/areas/{}/results".format(poll.area))
 
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:
            try:
                choice = Choice.objects.get(poll_id = poll.id,
                    candidate_id = candidate.id)
                rates.append(round(choice.votes * 100 / result['total_votes'], 1))
            except:#투표를 하나도 못받았을 경우. choice=0일때
                rates.append(0)
        result['rates'= rates #result안에 rates라는 키로 rates값을 넣음
        poll_results.append(result)
 
    context = {'candidates': candidates, 'area':area,
     'poll_results': poll_results}
    return render(request, 'elections/result.html', context)
cs

1.1. results함수 쪼개기

candidates에는 Candidate의 모든값을 불러오는데 조건이 현재 area값과 받아온 area값이 같은 모든 데이터를 저장합니다.

polls에는 Poll에 모든값중 현재 area값과 받아온 area값이 같은 조건의 값만을 저장합니다.

Ex) 해바라기반일때 해바라기반 친구들만, 장미반일때 장미반 친구들만

poll_results를 list로 만들어준다. 이곳에 전체 투표수를 넣어줄것입니다.



선거기간의 데이터를 넣어주기 위해 polls를 불러와 반복문을 써줍니다.

result라는 dictionary를 만들어줍니다. 그럼 이제 {시작일:날짜} , {끝나는날:날짜}로 데이터가 들어갈것입니다.

start_date라는 key에는 start_date의 value값을 넣어주고

end_date라는 kety애는 end_date의 value값을 넣어줍니다. 



total_votes에 총 투표수를 출력합니다.

models.py를 보시면 Choice함수 안에 votes들이 있습니다

Choice함수 안에 값들을 해당 id에 대한 값들만 불러오는데 votes값을 모두 더해서 가져온다

위에서 값을 넘겨줄때 dictionary 형으로 넘겨주기 때문에 사용하기 위하여 가공해줍니다.



(for문): 여러명의 친구들이 순서대로 저장이 되어야 하는데 이것은 candidate의 순서와 동일하므로 candidate를 반복문으로 돌려 리스트를 채우면 되므로 candidte를 반복문으로 돌려줍니다.


예외처리 try, exept: 투표를 하나도 못받았을 경우도 있기때문에 예외처리를 돌려줍니다. 이때 0을 그냥 넣어줍니다.


for문 이어서: choice에 값을 넣어주는데 조건을 poll(해당날짜), choice(선택)한 것들이 맞는 한행만 가져온다

get은 조건에 맞는 하나의 행만 가져오고, filter는 조건에 맞는 모든것을 가져온다는 뜻입니다.

rates에 값을 추가해주는데 현재 투표수*100에서 총 받은 갯수를 나눠 백분율로 표시합니다.

round는 반올림함수이며 1은 소수점 첫째자리까지 표시한다는 뜻입니다.


result['rates']안에 반복문을 통하여 추가했던 rates값들을 넣어줍니다.


result의 값을 poll_results에도 넣어줍니다.





2. 데이터를 받아줄 result.html표시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!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>    
    <tbody>
    {% endfor %}
</table>
</div>
</body>
cs


3. 결과확인

이렇게 백분율로 나오게 됩니다.







강의출처: http://tryhelloworld.co.kr/