일기 대신 코드 슬쩍

[백엔드][Django][장고 채널스]Section3.영어 상황극 채팅 웹 서비스, 사전작업 본문

Backend/Django

[백엔드][Django][장고 채널스]Section3.영어 상황극 채팅 웹 서비스, 사전작업

코코자 2023. 7. 24. 17:05

  • 웹서비스로 구현해보기 위해서는?
  1. 유저는 원하는 주제의 상황극 채팅방을 개설할 수 있어야 함→ 장고 기본 기능 활용(form,view)
  1. 유저는 서버와 1:1 채팅을 할 수 있어야하며, 즉각적인 메세지 전송이 필요함 → 웹소켓 by 장고 채널스
  1. 각 유저의 채팅방 messages 내역을 어딘가에 저장해야함 → 장고 채널스의 consumer 인스턴스 내에 저장하면 별도 인프라X

  • 새로운 프로젝트만들어서~migrate하고, superuser만들고, chat 애플리케이션 생성
  • settings가서 Installedapps에 ‘chat’추가
  • chat에서 urls.py생성
  • import 해주고 urlpatterns만들고,
  • mysite의 urls에서 path 추가해주기


  • 장고 시스템 메세지 한국어로 동작시키기 위해, settings에서 한국어로 설정하고, 환경변수로 api key 로딩하는 코드 작성


  • django-bootstrap5 라이브러리 적용할 것임
  • settings의 installedapps에 bootstrap5를 추가
  • chat/templates/chat/base.html 생성
{% load django_bootstrap5 %}




<!DOCTYPE html>

<html lang="ko">

    <head>

        <meta charset="UTF-8">

        <meta name="viewport"

              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

        <meta http-equiv="X-UA-Compatible" content="ie=edge">

        <title>장고 채널스와 함께 ChatGPT 영어 상황극 채팅 서비스 만들기</title>

        {% bootstrap_css %}

        {% bootstrap_javascript %}

        {% block extra-css %}{% endblock %}

    </head>

    <body>

        <div class="container">

            <header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">

                <a href="/"

                   class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none">

                    <span class="fs-4">장고 채널스와 함께 ChatGPT 영어 상황극 채팅 서비스 만들기</span>

                </a>




                <ul class="nav nav-pills">

                    <li class="nav-item">

                        <a href="#" class="nav-link active">새 상황 만들기</a>

                    </li>

                </ul>

            </header>

        </div>

        <div class="container">

            {% bootstrap_messages %}




            {% block content %}{% endblock %}




            <footer class="pt-4 my-md-5 pt-md-5 border-top">

                <div class="row">

                    <div class="col-12 col-md">

                        <small class="d-block mb-3 text-muted">&copy; 2023. 파이썬 사랑방</small>

                    </div>

                </div>

            </footer>




            {% block script %}{% endblock %}

        </div>

    </body>

</html>


  • 장고 부트스트랩 추천 설정
  • 필수 필드추가, 필수 필드는 볼드체로 적용
  • settings에 bootstrap5 설정 추가
BOOTSTRAP5 = {
    "required_css_class": "fw-bold",
    "set_placeholder": False,
}


  • 상황극 채팅방 설정을 담는 장고 모델 설계 및 마이그레이션
  • 상황극 채팅방 개설에는 1)언어, 2) 레벨, 3) 상황(영문), 4) 내 역할(영문), 5) GPT 역할(영문) 설정해줘야 함 (+ 한글로 기입하면 시스템에서 영문으로 변환해주는 기능도)
  • 이 항목들을 ORM인 장고 모델을 활용해 데이터베이스 관리해줄 것임
  • models.py
from django.conf import settings
from django.db import models


class RolePlayingRoom(models.Model):
    class Language(models.TextChoices):
        ENGLISH = "en-US", "English"
        JAPANESE = "ja-JP", "Japanese"
        CHINESE = "zh-CN", "Chinese"
        SPANISH = "es-ES", "Spanish"
        FRENCH = "fr-FR", "French"
        GERMAN = "de-DE", "German"
        RUSSIAN = "ru-RU", "Russian"

    class Level(models.TextChoices):
        BEGINNER = 1, "초급"
        ADVANCED = 2, "고급"

    class Meta:
        ordering = ["-pk"]

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    language = models.CharField(
        max_length=10,
        choices=Language.choices,
        default=Language.ENGLISH,
        verbose_name="대화 언어",
    )
    level = models.SmallIntegerField(
        choices=Level.choices, default=Level.BEGINNER, verbose_name="레벨"
    )
    situation = models.CharField(max_length=100, verbose_name="상황")
    situation_en = models.CharField(
        max_length=100,
        blank=True,
        verbose_name="상황 (영문)",
        help_text="GPT 프롬프트에 직접적으로 활용됩니다. 비워두시면, situation 필드를 번역하여 자동 반영됩니다.",
    )
    my_role = models.CharField(max_length=100, verbose_name="내 역할")
    my_role_en = models.CharField(
        max_length=100,
        blank=True,
        verbose_name="내 역할 (영문)",
        help_text="GPT 프롬프트에 직접적으로 활용됩니다. 비워두시면, my_role 필드를 번역하여 자동 반영됩니다.",
    )
    gpt_role = models.CharField(max_length=100, verbose_name="GPT 역할")
    gpt_role_en = models.CharField(
        max_length=100,
        blank=True,
        verbose_name="GPT 역할 (영문)",
        help_text="GPT 프롬프트에 직접적으로 활용됩니다. 비워두시면, gpt_role 필드를 번역하여 자동 반영됩니다.",
    )
  • makemigrations 했을 때 에러 나면? powershell에 이렇게 입력) $env:OPENAI_API_KEY = "”
  • migrate까지 해주기


  • 구글 번역 모바일 페이지 크롤링을 통한 번역
  • chat/translators.py 생성
from typing import Literal

import requests
from bs4 import BeautifulSoup


def google_translate(
    text: str,
    source: Literal["auto", "en", "ko"],
    target: Literal["en", "ko"],
):
    text = text.strip()
    if not text:
        return ""

    endpoint_url = "https://translate.google.com/m"

    params = {
        "hl": source,
        "sl": source,
        "tl": target,
        "q": text,
        "ie": "UTF-8",
        "prev": "_m",
    }

    headers = {
        "User-Agent": (
            "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 "
            "(KHTML, like Gecko) Chrome/86.0.4240.183 Mobile Safari/537.36"
        ),
    }

    res = requests.get(
        endpoint_url,
        params=params,
        headers=headers,
        timeout=5,
    )
    res.raise_for_status()

    soup = BeautifulSoup(res.text, "html.parser")
    translated_text = soup.select_one(".result-container").text.strip()

    return translated_text