0. 이 글은 누구를 위한 글인가요?
- VS Code에서 Django 설치, 서버 실행까지는 해봤어요.
- 이제 사용자가 키워드를 입력하고, 결과를 웹에서 보여주는 기능을 만들고 싶어요.
- views, urls, templates의 구조와 연결 흐름이 궁금해요!
1. 실습 목표
단계 | 기능 |
1 | 사용자 키워드 입력 폼 만들기 |
2 | 입력된 키워드를 views.py에서 처리 |
3 | 뉴스 수집 + 감성 분석 + 요약 적용 |
4 | 결과를 웹페이지에 출력 |
2. Django 앱 생성 및 설정
2-1. analyzer 앱 생성
python manage.py startapp analyzer
2-2. settings.py 설정
# config/settings.py
INSTALLED_APPS = [
...
'analyzer',
]
2-3. 기본 폴더 구조
my_django_project/
├── config/
├── analyzer/
│ ├── views.py
│ ├── urls.py ← 직접 생성
│ └── templates/analyzer/
│ ├── form.html
│ └── result.html
3. URL 설정
3-1. analyzer/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
path('result/', views.result, name='result'),
]
3-2. config/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('analyzer.urls')),
]
4. HTML 템플릿
4-1. form.html
<!DOCTYPE html>
<html>
<head><title>뉴스 분석기</title></head>
<body>
<h1>뉴스 키워드 분석</h1>
<form method="POST" action="{% url 'result' %}">
{% csrf_token %}
<label for="keyword">검색할 키워드를 입력하세요:</label>
<input type="text" id="keyword" name="keyword" required>
<button type="submit">분석 시작</button>
</form>
</body>
</html>
4-2. result.html
<!DOCTYPE html>
<html>
<head><title>분석 결과</title></head>
<body>
<h1>뉴스 분석 결과</h1>
<p><strong>입력 키워드:</strong> {{ keyword }}</p>
<table border="1">
<tr>
<th>제목</th>
<th>감성</th>
<th>요약</th>
</tr>
{% for row in results %}
<tr>
<td>{{ row.title }}</td>
<td>{{ row.sentiment }}</td>
<td>{{ row.summary }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
5. views.py 작성 (analyzer/views.py)
from django.shortcuts import render
from transformers import AutoTokenizer, AutoModelForSequenceClassification
from transformers import BartTokenizer, BartForConditionalGeneration
import torch
import torch.nn.functional as F
import requests
from bs4 import BeautifulSoup
# 모델 로딩
sa_tokenizer = AutoTokenizer.from_pretrained("beomi/KcELECTRA-base")
sa_model = AutoModelForSequenceClassification.from_pretrained("beomi/KcELECTRA-base")
sum_tokenizer = BartTokenizer.from_pretrained("digit82/kobart-summarization")
sum_model = BartForConditionalGeneration.from_pretrained("digit82/kobart-summarization")
def collect_titles(keyword, pages=1):
headers = {'User-Agent': 'Mozilla/5.0'}
titles = []
for page in range(1, pages + 1):
start = (page - 1) * 10 + 1
url = f"https://search.naver.com/search.naver?where=news&query={keyword}&start={start}"
res = requests.get(url, headers=headers)
soup = BeautifulSoup(res.text, 'html.parser')
for a in soup.select("a.news_tit"):
titles.append(a.get_text())
return titles[:10]
def get_sentiment(text):
inputs = sa_tokenizer(text, return_tensors="pt", truncation=True)
with torch.no_grad():
logits = sa_model(**inputs).logits
pred = torch.argmax(F.softmax(logits, dim=1)).item()
return ['부정', '중립', '긍정'][pred]
def summarize(text, max_len=40):
input_ids = sum_tokenizer.encode(text, return_tensors='pt', truncation=True)
output_ids = sum_model.generate(input_ids, max_length=max_len, num_beams=4, early_stopping=True)
return sum_tokenizer.decode(output_ids[0], skip_special_tokens=True)
def index(request):
return render(request, 'analyzer/form.html')
def result(request):
if request.method == 'POST':
keyword = request.POST['keyword']
titles = collect_titles(keyword)
results = []
for t in titles:
sentiment = get_sentiment(t)
summary = summarize(t)
results.append({'title': t, 'sentiment': sentiment, 'summary': summary})
return render(request, 'analyzer/result.html', {'keyword': keyword, 'results': results})
6. 실행 및 출력 예시
python manage.py runserver
- 브라우저에서 접속:
http://127.0.0.1:8000
입력 예시
입력 키워드: 인공지능
출력 예시
제목 | 감성 | 요약 |
AI가 바꾸는 미래 일자리 | 긍정 | AI가 일자리를 변화시킨다 |
AI 범죄 경고 | 부정 | AI 관련 위험성 제기 |