manage.py
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
이 코드는 Django 프로젝트에서 명령어(예: runserver, migrate 등)를 실행할 때 여러 가지 관리 작업을 도와주는 도구이다. manage.py 파일의 역할을 하며 Django 환경 변수를 설정하고, 명령어를 파싱하여 적절한 명령을 실행하는 역할을 한다.
#!/usr/bin/env python
- 쉘 스크립트로 인식될 때 사용되는 쉐뱅(shebang)이다. Python 인터프리터 경로를 지정하여, 이 파일을 바로 실행할 수 있게 한다. env 명령을 통해 Python이 시스템 환경에서 자동으로 검색되도록 하고 있다.
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoProject.settings')
- Django의 관리 명령을 처리하기 위한 진입점으로 사용
- os.environ.setdefault: Django 환경 변수를 설정.
- 'DJANGO_SETTINGS_MODULE'은 Django 프로젝트의 설정 파일을 가리키는 환경 변수이다. 이 코드에서는 'djangoProject.settings'로 지정되어 있는데, 이는 Django 프로젝트의 설정 파일 경로이다.
try:
from django.core.management import execute_from_command_line
- execute_from_command_line는 Django의 명령줄 명령을 실제로 실행하는 함수. 명령어와 관련된 인자를 처리하고, 적절한 Django 명령을 실행한다.
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
- ImportError: django.core.management 모듈을 불러오지 못하면 발생하는 예외. 보통 Django가 설치되지 않았거나, 가상 환경이 활성화되지 않았을 때 발생하고 이 경우 사용자에게 Django가 설치되지 않았음을 알리는 메시지를 출력한다.
execute_from_command_line(sys.argv)
- sys.argv: 명령줄에서 입력된 인자 목록을 나타낸다. 이를 통해 Django 명령을 처리하고 실행한다.
- 예를 들어, python manage.py runserver 명령을 입력하면 이 명령어가 sys.argv를 통해 전달된다.
if __name__ == '__main__':
main()
- 파일이 직접 실행될 때만 main 함수를 호출한다. 다른 파일에서 이 모듈로 불러온다면(다른 파이썬 파일에서 해당 파일의 함수나 클래스를 가져다 사용) main 함수는 실행되지 않는다.
MVT 패턴
백엔드 코드를 보려면 Django 프로젝트의 앱(app) 폴더 안에 있는 파일들을 확인해야 한다. Django는 MVC 패턴을 기반으로 동작하는 웹 프레임워크인데, 여기서는 이를 MTV 패턴이라고 부른다. 즉, 모델(Model), 템플릿(Template), 뷰(View)로 구성되어 있다.
models.py
이 파일에는 데이터베이스 테이블의 구조를 정의하는 코드가 들어있다. 모델을 정의하면 Django가 이 구조에 맞춰 데이터베이스 테이블을 생성하고, 데이터를 저장하거나 조회하는 기능을 제공한다.
#데이터베이스와 상호작용하는 모델을 정의할 때 사용하는 클래스와 도구들이 포함된 모듈 import
from django.db import models
#데이터베이스에서 파일 업로드와 관련된 정보를 저장하는 테이블이 생성
class UploadedFile(models.Model):
#파일을 다루는 필드이며, csvs/ 폴더에 저장됨
file = models.FileField(upload_to='csvs/')
#파일이 언제 업로드되었는지를 기록하고, 그 값은 처음 업로드될 때 자동으로 설정
uploaded_at = models.DateTimeField(auto_now_add=True)
파일 업로드를 다루기 위한 모델이며 각 필드는 파일 정보와 업로드 시점을 저장한다.
views.py
from django.shortcuts import render
import pandas as pd
import hashlib
import os
from .forms import CsvProcessForm
from django.conf import settings
def mask_string(value, mask_char='*'):
"""일반 문자열을 마스킹 처리하는 함수"""
if value:
return value[0] + mask_char * (len(value) - 1)
return value
def sha256_encode(value):
"""문자열을 SHA-256으로 암호화하는 함수"""
return hashlib.sha256(value.encode()).hexdigest() if value else value
def process_csv(file_path, operations):
"""CSV 파일을 읽고 주어진 작업(마스킹, 해싱, 삭제)을 수행하는 함수"""
# CSV 파일 읽기
data = pd.read_csv(file_path, encoding='utf-8-sig')
# 각 필드에 대해 주어진 작업 수행
for field_name, operation in operations:
if operation == 'mask':
if field_name in data.columns:
data[field_name] = data[field_name].apply(mask_string)
elif operation == 'hash':
if field_name in data.columns:
data[field_name] = data[field_name].apply(sha256_encode)
elif operation == 'delete':
if field_name in data.columns:
data.drop(columns=[field_name], inplace=True)
return data
def upload_csv(request):
"""CSV 파일 업로드 및 처리 뷰"""
if request.method == 'POST':
# 추가된 필드의 수를 파악
additional_fields_count = len([key for key in request.POST if key.startswith('additional_field_name_')])
# 폼에 추가된 필드의 수를 전달하여 초기화
form = CsvProcessForm(request.POST, request.FILES, additional_fields_count=additional_fields_count)
if form.is_valid():
# 기본 필드 처리
csv_file = form.cleaned_data['file']
field_name = form.cleaned_data['field_name']
operation = form.cleaned_data['operation']
output_file_name = form.cleaned_data['output_file_name']
# 처음 필드와 작업 추가
operations = [(field_name, operation)]
# 추가 필드 및 작업 수집
for i in range(1, additional_fields_count + 1):
additional_field_name = form.cleaned_data.get(f'additional_field_name_{i}')
additional_operation = form.cleaned_data.get(f'additional_operation_{i}')
if additional_field_name and additional_operation:
operations.append((additional_field_name, additional_operation))
# 파일 저장 경로 생성
if not os.path.exists(settings.MEDIA_ROOT):
os.makedirs(settings.MEDIA_ROOT)
uploaded_file_path = os.path.join(settings.MEDIA_ROOT, csv_file.name)
with open(uploaded_file_path, 'wb+') as destination:
for chunk in csv_file.chunks():
destination.write(chunk)
# CSV 처리
processed_data = process_csv(uploaded_file_path, operations)
output_path = os.path.join(settings.MEDIA_ROOT, f'{output_file_name}.csv')
processed_data.to_csv(output_path, index=False, encoding='utf-8-sig')
# 다운로드 페이지로 리다이렉트
return render(request, 'download.html', {'file_url': f'/media/{output_file_name}.csv'})
else:
form = CsvProcessForm()
return render(request, 'upload.html', {'form': form})
CSV 파일을 업로드하고 처리하는 기능을 구현한 뷰이다.
forms.py
from django import forms
class CsvProcessForm(forms.Form):
#csv파일 업로드
file = forms.FileField(label='CSV 파일')
#처리할 필드명 입력
field_name = forms.CharField(label='필드명')
#필드에 수행할 작업 선택
operation = forms.ChoiceField(label='작업 선택', choices=[('mask', '마스킹'), ('hash', '암호화'), ('delete', '삭제')])
#처리된 파일의 출력 파일명
output_file_name = forms.CharField(label='출력 파일명', required=False)
def __init__(self, *args, **kwargs):
# 동적으로 생성할 추가 필드의 수를 결정
additional_fields_count = kwargs.pop('additional_fields_count', 0)
#추가 필드 및 작업 선택을 동적으로 생성하여 폼에 추가
super().__init__(*args, **kwargs)
#동적 필드 추가
for i in range(1, additional_fields_count + 1):
self.fields[f'additional_field_name_{i}'] = forms.CharField(label=f'추가 필드명 {i}', required=False)
self.fields[f'additional_operation_{i}'] = forms.ChoiceField(label=f'작업 선택 {i}',
choices=[('mask', '마스킹'), ('hash', '암호화'), ('delete', '삭제')],
required=False)
사용자가 업로드할 CSV 파일과 처리할 필드 및 작업에 대한 정보를 입력받기 위한 폼을 제공한다.
HTML
templates 폴더 안에 있는 html 파일이다. 우선 제일 기본적이고 심플한 형태로만 구현을 해놓아서 추가 회의 후 html 코드는 수정이 될 수 있다..
download.html
파일 다운로드를 알리고 사용자가 다운로드 버튼을 클릭하여 파일을 받을 수 있도록 하는 역할
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>파일 다운로드</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f9f9f9;
color: #333;
}
h1 {
text-align: center;
margin-top: 50px;
font-size: 24px;
color: #020202;
}
p {
text-align: center;
margin: 20px;
font-size: 16px;
}
a {
text-align: center;
display: block;
margin: 0 auto;
width: 200px;
}
button {
display: block;
width: 100%;
padding: 10px;
font-size: 16px;
color: #fff;
background-color: #020202;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #020202;
}
</style>
</head>
<body>
<h1>파일 처리가 완료되었습니다</h1>
<p>아래 버튼을 눌러 파일을 다운로드하세요:</p>
<a href="{{ file_url }}" download>
<button type="button">다운로드</button>
</a>
</body>
</html>
upload.html
CSV 파일을 업로드하고 처리하기 위한 폼을 제공하는 웹 페이지이다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>CSV 파일 처리</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f9f9f9;
color: #333;
}
h1 {
text-align: center;
margin-top: 20px;
font-size: 24px;
color: #020202;
}
form {
max-width: 500px;
margin: 20px auto;
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
label {
font-weight: bold;
margin-bottom: 5px;
display: block;
}
input[type="text"], input[type="file"], select {
width: 100%;
padding: 8px;
margin-bottom: 15px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
button {
display: inline-block;
padding: 10px 15px;
font-size: 16px;
color: #fff;
background-color: #020202;
border: none;
border-radius: 4px;
cursor: pointer;
text-align: center;
margin-top: 10px;
}
button:hover {
background-color: #020202;
}
.field-group {
margin-bottom: 15px;
}
.add-button {
background-color: #020202;
margin-bottom: 20px;
}
.add-button:hover {
background-color: #020202;
}
.output-container {
margin-top: 20px;
}
</style>
<script>
let fieldCount = 1;
function addField() {
fieldCount++;
const container = document.getElementById('field-container');
const div = document.createElement('div');
div.setAttribute('id', `field-group-${fieldCount}`);
div.setAttribute('class', 'field-group');
const fieldNameLabel = document.createElement('label');
fieldNameLabel.textContent = '필드명: ';
div.appendChild(fieldNameLabel);
const fieldNameInput = document.createElement('input');
fieldNameInput.setAttribute('type', 'text');
fieldNameInput.setAttribute('name', `additional_field_name_${fieldCount}`);
div.appendChild(fieldNameInput);
const operationLabel = document.createElement('label');
operationLabel.textContent = '작업 선택: ';
div.appendChild(operationLabel);
const operationSelect = document.createElement('select');
operationSelect.setAttribute('name', `additional_operation_${fieldCount}`);
operationSelect.innerHTML = `
<option value="mask">마스킹</option>
<option value="hash">암호화</option>
<option value="delete">삭제</option>
`;
div.appendChild(operationSelect);
container.appendChild(div);
}
</script>
</head>
<body>
<h1>CSV 파일 처리</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div>
<label>{{ form.file.label_tag }}</label>
{{ form.file }}
</div>
<div>
<label>{{ form.field_name.label_tag }}</label>
{{ form.field_name }}
</div>
<div>
<label>{{ form.operation.label_tag }}</label>
{{ form.operation }}
</div>
<!-- 추가 필드를 위한 컨테이너 -->
<div id="field-container"></div>
<button type="button" class="add-button" onclick="addField()">+ 추가 필드</button>
<div class="output-container">
<label>{{ form.output_file_name.label_tag }}</label>
{{ form.output_file_name }}
</div>
<button type="submit">업로드 및 처리</button>
</form>
</body>
</html>
실행 결과
터미널에 python manage.py runserver를 입력하여 실행을 해준다.
※여기서 주의할 점은 현재 디렉토리가 어디있는지이다. djangoProject가 있는 곳으로 디렉토리 경로를 수정 후 터미널에 입력을 해야 실행이 된다.
나의 경우 djangoProject 안에 djangoProject 안에 manage 파일이 있기 때문에 이에 맞춰 디렉토리를 이동해준다.
실행을 하면 url이 나오는데 여기를 들어간다.
여기서 주의할 점은 마지막에 /upload를 꼭 붙여주어야한다! 왜 그런지 자세히는 모르겠지만 URL 패턴에 정의된 특정 뷰(View)를 호출하기 위해 필요한 경로라 붙여야하는 듯하다...
이렇게 웹페이지가 나온다! CSV 파일을 선택하고 비식별화 처리 할 필드명을 입력한 후 그 방식을 선택한다. 마지막으로 비식별화 처리된 파일의 이름을 직접 지정하고 업로드 및 처리를 누르면 완성된다.
오류
현재 이 웹페이지에는 몇가지 오류가 있다. 팀원들과 회의를 통해 하나씩 수정해나갈 것이다!
- 범주화 기능 없음
- 파일에 한국어가 들어갈 시 실행이 안됨(아마 제일 큰 오류일듯 하다...)
'2024 여름 SWLUG > 개인정보보호 프로젝트' 카테고리의 다른 글
데이터 비식별화 처리 웹페이지 구현 - 최종 (0) | 2024.09.02 |
---|---|
[파이썬]데이터 비식별화 코드 최종 + 웹 개발 기초 및 기획 (0) | 2024.08.18 |
[파이썬] 데이터 비식별화 처리 (0) | 2024.08.08 |
[R프로그래밍] 데이터 비식별화 처리 코드 실습 (0) | 2024.08.04 |
R Studio CSV 파일 불러오기 (0) | 2024.07.28 |