본문 바로가기
웹 개발 실습/Django

[Django]_엑셀 계산 사이트 만들기 (6) result, loginFail 페이지 만들기, 그리고 번외(django에서 누가 봐도 깔끔하게 자료 만들기)

by ssolLEE 2023. 8. 3.
반응형

이 프로젝트도 마찬가지로 책 'Django 한 그릇 뚝딱'의 Chapter 4을 보며 실행해보았습니다. 책의 저자님께 다시 한 번 감사말씀 드립니다.

 

 

Result 페이지 만들기

 

  • 이메일도, 메인도 모두 세션에 담겠습니다. 
  • 또한 Pandas와 Django 데이터 타입이 조금 다릅니다. 그래서 우리는 Pandas의 데이터 타입을 기본 데이터 타입으로 변환해야 합니다.
  • ExcelCalculate > calculate > views.py로 이동하여 calculate 함수에  다음 코드를 추가합니다.
# pandas django데이터 타입이 조금 다름
    grade_calculate_dic_to_session = {}
    for key in grade_list:
        grade_calculate_dic_to_session[int(key)] = {}
        grade_calculate_dic_to_session[int(key)]['max'] = float(grade_calculate_dic[key]['max']) # float 자료형으로 변환
        grade_calculate_dic_to_session[int(key)]['avg'] = float(grade_calculate_dic[key]['avg']) # float 자료형으로 변환
        grade_calculate_dic_to_session[int(key)]['min'] = float(grade_calculate_dic[key]['min']) # float 자료형으로 변환
        
    request.session['grade_calculate_dic'] = grade_calculate_dic_to_session
    request.session['email_domain_dic'] = email_domain_dic
  • ExcelCalculate > main > views.py로 이동하여 result 함수 코드를 수정합니다.
def result(request):
    if 'user_name' in request.session.keys():
        content = {}
        # 새로운 객체에 저장
        content['grade_calculate_dic'] = request.session['grade_calculate_dic']
        content['email_domain_dic'] = request.session['email_domain_dic']

        # 기존 세션 삭제
        del request.session['grade_calculate_dic']
        del request.session['email_domain_dic']

        return render(request, "main/result.html", content)
  • ExcelCalculate > main > tempaltes > main > result.html 로 이동하여  40~45번째 줄을 지우고 다음 코드를 붙여넣습니다.
        <div class='body'>
            <div class="resultDiv">
                <h3> * Excel 결과 확인 *</h3>
                <h4> - grade별 최솟값, 최댓값, 평균값</h4>
                {% for key, value in grade_calculate_dic.items %}
                    <h5>GRADE: {{ key }}</h5>
                    <p><strong>최솟값 : </strong> {{ value.min }}</p>
                    <p><strong>최댓값 : </strong> {{ value.max }}</p>
                    <p><strong>평균값 : </strong> {{ value.avg }}</p>
                    <br>
                {% endfor %}
                <br>
                <h4> - 이메일별 주소 도메인 인원 </h4>
                {% for key, value in email_domain_dic.items %}
                    <p><strong>{{ key }}: </strong> {{ value }}명</p>
                {% endfor %}
            </div>
            <hr>
        </div>

 

 

loginFail 페이지 만들기

 

  • ExcelCalculate > main > views.py로 이동하여 로그인 실패 시 어떤 url로 갈 지 설정합니다.
  • user가 로그인을 시도하면 user 모델에 접근하여 user가 입력한 이메일로 탐색을 시도합니다.
  • 회원 미가입 또는 비밀번호가 틀리다면 에러가 발생합니다.
  • 이때 필요한 것이 바로 try-except 구문입니다.log 함수를 다음과 같이 수정합니다.
def login(request):
    loginEmail = request.POST['loginEmail']
    loginPW = request.POST['loginPW']
    try:
        user = User.objects.get(user_email = loginEmail)
    except: 
        return redirect('main_loginFail')
    if user.user_password == loginPW:
        request.session['user_name'] = user.user_name
        request.session['user_email'] = user.user_email
        return redirect('main_index')
    else:
        return redirect('main_loginFail')
  • ExcelCalculate > main > urls.py로 이동하여 로그인 실패에 대한 url을 추가합니다.
path('loginFail', views.loginFail, name="main_loginFail"),
  • ExcelCalculate > main > views.py로 이동하여 loginFail 함수를 만들겠습니다. 
def loginFail(request):
    return render(request, 'main/loginFail.html')
  • ExcelCalculate > main > tempaltes > main > loginFail.html 파일을 만들어 다음 코드를 붙여넣습니다. 이는 보여질 화면을 세팅한 것입니다.
<html lang="ko">
<head>
    <meta charset="UTF-8">

    <!-- Boot strap -->
    <!-- 합쳐지고 최소화된 최신 CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
    <!-- 부가적인 테마 -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">
    <!-- 합쳐지고 최소화된 최신 자바스크립트 -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

    <style>
        .panel-footer{
            height:10%;
            color:gray;
        }
    </style>
    <title>Excel Calculate</title>
</head>
<body>
    <div class="container">
        <div class="header">
            <div class="page-header">
                <a href="/" class="btn btn-default btn-xs" style="margin: 10px">메인화면</a>
                <h1>Excel Calculate <small>with Django</small></h1>
            </div>
        </div>
        <div class='body'>
            <h1>로그인 실패</h1>
            <h4>아이디 또는 비밀번호가 틀렸습니다. 로그인을 다시 시도해주세요.</h4>
            <a href="/signin" class="btn btn-success btn-xs" style="margin: 10px">로그인 하기</a>
        </div>
        <div class="panel-footer">
            실전예제로 배우는 Django. Project3-ExcelCalculate
        </div>
    </div>
</body>
</html>

 

번외

다음은 정지훈 강사님(Data Science | DSChloe)의 코드 입니다.

자료를 더 깔끔하게 정리하기 위해서 pandas to html 등을 검색해서 개인공부를 하면 좋습니다.

저도 공부가 진행되면 포스팅을 올리겠습니다.

감사합니다.

  • result.html 

  • calculate > views.py 
from django.shortcuts import render, redirect
from django.http import HttpResponse
import pandas as pd
import json
​
# Create your views here.
def calculate(request):
    file = request.FILES['fileInput']
    print("# 사용자가 등록한 파일의 이름: ", file)
    df = pd.read_excel(file, sheet_name="Sheet1", header=0)
    print(df.head())
    # grade별 value 리스트 만들기
    grade_dic = {}
    total_row_num = len(df.index)
    for i in range(total_row_num):
        data = df.loc[i, :]
        if not data.grade in grade_dic.keys():
            grade_dic[data.grade] = [data.value]
        else:
            grade_dic[data.grade].append(data.value)
​
    # print(grade_dic)
    # grade별 최솟값 최댓값 평균값 구하기
    grade_calculate_dic = {}
    for key in grade_dic.keys():
        grade_calculate_dic[key] = {}
        grade_calculate_dic[key]['min'] = min(grade_dic[key])
        grade_calculate_dic[key]['max'] = max(grade_dic[key])
        grade_calculate_dic[key]['avg'] = float(sum(grade_dic[key])) / len(grade_dic[key])
​
    # 결과 출력
    grade_list = list(grade_calculate_dic.keys())
    grade_list.sort()
    for key in grade_list:
        print("# grade: ", key)
        print("min:", grade_calculate_dic[key]['min'], end="")
        print("/ max:", grade_calculate_dic[key]['max'], end="")
        print("/ avg:", grade_calculate_dic[key]['avg'], end="\n\n")
​
    # 이메일 주소 도메인별 인원 구하기
    email_domain_dic = {}
    for i in range(total_row_num):
        data = df.loc[i, :]
        email_domain = data['email'].split("@")[1]
        if not email_domain in email_domain_dic.keys():
            email_domain_dic[email_domain] = 1
        else:
            email_domain_dic[email_domain] += 1
    print("## EMAIL 도메인별 사용 인원")
    for key in email_domain_dic.keys():
        print("#", key, ": ", email_domain_dic[key], "명")
​
    grade_calculate_dic_to_session = {}
    for key in grade_list:
        grade_calculate_dic_to_session[int(key)] = {}
        grade_calculate_dic_to_session[int(key)]['max'] = float(grade_calculate_dic[key]['max'])
        grade_calculate_dic_to_session[int(key)]['avg'] = float(grade_calculate_dic[key]['avg'])
        grade_calculate_dic_to_session[int(key)]['min'] = float(grade_calculate_dic[key]['min'])
        
    request.session['grade_calculate_dic'] = grade_calculate_dic_to_session
    request.session['email_domain_dic'] = email_domain_dic
​
    # grade별 value 리스트 만들기
    grade_df = df.groupby('grade')['value'].agg(["min", "max", "mean"]).reset_index().rename(columns = {"mean" : "avg"})
    grade_df = grade_df.astype({'min' : 'int', 'max' : 'int', 'avg' : 'float'})
    print(grade_df.dtypes)
    grade_df = grade_df.style.hide(axis='index').set_table_attributes('class="table table-dark"')
    grade_calculate_pd_to_session = {'grade_df' : grade_df.to_html(justify='center')}
    request.session['grade_calculate_pd_dic'] = grade_calculate_pd_to_session
​
    # 이메일 주소 도메인별 인원 구하기
    df['domain'] = df['email'].apply(lambda x : x.split("@")[1])
    email_df = df.groupby('domain')['value'].agg("count").sort_values(ascending=False).reset_index()
​
    email_df = email_df.style.hide(axis='index').set_table_attributes('class="table table-dark"')
    
    email_calculate_pd_to_session = {'email_df' : email_df.to_html(justify='center')}
    request.session['email_calculate_pd_dic'] = email_calculate_pd_to_session
​
​
        # print(email_df)
​
    # return HttpResponse("calculate, calculate function!")
    return redirect('/result')

감사합니다.