Skip to content

Create Django Package 2

Jangwon edited this page Jun 14, 2018 · 1 revision

Overview

현재 Python 가상환경에 Django가 설치되었다고 가정하고 개발을 진행했다.

How to create your first Django library 블로그를 참고했다.

Application 생성하기

Contact-Form 파일을 생성하고 Tirrilee_Contact_Form이라는 Django App을 생성한다.

$ mkdir Contact-Form && cd Contact-Form
$ django-admin.py startapp Tirrilee_Contact_Form

README 파일과 LICENSE 파일을 추가한다.

$ touch README.md
$ touch LICENSE

Contact Form 만들기

Django App을 만들면 자동으로 생성되는 admin.py, apps.py, models.py는 삭제한다.

Tirrilee_Contact_Form/forms.py

템플릿에 뿌려주는 폼을 설정하고, form.save 기능을 통해 템플릿에서 입력받은 정보를 메일로 보내는 역할

from django.template.loader import render_to_string # HTML/txt 메세지 포멧을 String으로 변환
from smtplib import SMTPException        # 메일 전송 오류를 확인
from django.core import mail             # 메일 전송을 위한 내장 함수
from django import forms                 #

class ContactForm(forms.Form):
    name = forms.CharField(label="이름", max_length=100)           # 이름 input
    email = forms.EmailField(label="메일")                         # 메일 input
    subject = forms.CharField(label="제목", max_length=250)        # 제목 input
    message = forms.CharField(label="내용", widget=forms.Textarea) # 내용 input
    file = forms.FileField(label="첨부파일")                        # 파일 input

    subject_intro = settings.SUBJECT_INTRO                        # 제목 인트로
    from_email = settings.FROM_EMAIL                              # 보내는 메일
    email_recipients = settings.EMAIL_RECIPIENTS                  # 받는 메일 리스트
    template_name = 'tirrilee_contact_form/email_body.txt'        # txt 메세지 포멧
    html_template_name = 'tirrilee_contact_form/email_body.html'  # HTML 메세지 포멧

    def __init__(self, *args, **kwargs):
        for kwarg in list(kwargs):
            if hasattr(self, kwarg):
                setattr(self, kwarg, kwargs.pop(kwarg))
        super(ContactForm, self).__init__(*args, **kwargs)

    def save(self):
        # 데이터 받아오기
        subject = self.get_subject()
        from_email = self.get_from_email()
        email_recipients = self.get_email_recipients()
        context = self.get_context()
        file = self.get_file()
        message_body = render_to_string(self.get_template_names(), context)

        # 메일을 보낸다. 오류가 발생하면 
        try:
            # 제목, 내용, 보내는 메일, 받는 메일, 헤더 정보를 담은 메세지
            message = mail.EmailMultiAlternatives(
                subject=subject,
                body=message_body,
                from_email=from_email,
                to=email_recipients,
                headers={
                    'Reply-To': self.cleaned_data['email']
                }
            )
            if settings.USE_HTML_EMAIL: # HTML 메세지를 전송할 경우
                html_body = render_to_string(self.html_template_name, context)
                message.attach(file.name, file.read(), file.content_type) # 첨부 파일 추가
                message.attach_alternative(html_body, "text/html")        # 파일 내용 추가
            message.send()                                                # 메일 전송! 

        except SMTPException:
            print("메일 전송 오류")
            return False
        else:
            return True

    # json 형식의 전체 내용
    def get_context(self):
        return self.cleaned_data.copy()

    # 제목 인트로 + 제목
    def get_subject(self):
        return self.subject_intro + self.cleaned_data['subject']
    
    # settings에서 설정한 디폴트 메일
    def get_from_email(self):
        return self.from_email

    # settings에서 받는 메일 리스트
    def get_email_recipients(self):
        return self.email_recipients

    # 템플릿에서 입력 받은 파일
    def get_file(self):
        return self.cleaned_data['file']

    # 메세지 랜더를 위한 txt 파일
    def get_template_names(self):
        return self.template_name

Tirrilee_Contact_Form/views.py

FormView를 사용해 입력받은 Form의 유효성을 검사하고, URL을 통해 템플릿을 뿌려준다.

class ContactView(FormView):
    form_class = ContactForm
    template_name = 'tirrilee_contact_form/contact_form.html'
    success_url = '/'

    # Form이 유효할 경우 form.save를 실행시켜 메일을 전송한다.
    def form_valid(self, form):
        form.save()
        return redirect(self.get_success_url())

    # 유효하지 않을 경우 Form을 Context data로 템플릿에 넘긴다
    def form_invalid(self, form):
        return self.render_to_response(self.get_context_data(form=form))

Tirrilee_Contact_Form/urls.py

urlpatterns = [
    url(r'^$', ContactView.as_view(), name='envelope-contact'),
]

테스트 하기

Contact-Form/test_settings.py

서버를 실행시키기 위한 가장 기본적인 세팅 값들만 입력합니다.

DEBUG = True

ALLOWED_HOSTS = []

ROOT_URLCONF = 'Tirrilee_Contact_Form.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
            ],
        },
    },
]

INSTALLED_APPS = (

    'Tirrilee_Contact_Form',
)
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': ':memory:',
    }
}
SECRET_KEY = "secret_key_for_testing"

# 구글!!! 이메일 세팅
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# Django 내장 라이브러리를 Import 한다.
EMAIL_HOST = 'smtp.gmail.com'
# 메일을 호스트하는 서버이고 gmail을 사용할 것 이다.
EMAIL_PORT = '587'
# gmail에서 권장하는 이메일 통신 포트이다.
EMAIL_HOST_USER = 'example@example.com'
# 발신할 이메일 입력한다.
EMAIL_HOST_PASSWORD = 'yourpassword'
# 발신할 이메일 비밀번호를 입력한다.
EMAIL_USE_TLS = True
# TLS 사용 여부에 대한 설정이고 TLS는 보안 방법 중 하나이다.
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
# 사이트와 관련한 자동응답을 받을 이메일 주소로 기본값은 'webmaster@localhost'라고 한다.

TIRRILEE_SUBJECT_INTRO = '[고객문의] '

Django 서버를 실행할 수 있도록 settings 파일을 정의하고 runserver를 합니다.

$ django-admin.py runserver --settings=test_settings

결과

Contact-Form
├── Tirrilee_Contact_Form              # 
│   ├── migrations                     #
│   │   └── ...                        # 
│   ├── __init__.py                    # 패키지 인식을 위한 초기 파일
│   ├── forms.py                       # 새로 생성한 파일
│   ├── urls.py                        #
│   ├── settings.py                    # 메일 전송을 위한 디폴트 값 세팅
│   ├── urls.py                        #
│   └── view.py                        #
├── LICENSE                            # 패키지의 라이센스 정보를 갖는 파일 
├── MANIFEST.in                        # 
├── README.md                          # 해당 패키지를 설명하는 README 파일
├── setup.py                           # 패키지에 대한 전체 정보를 갖는 파일
└── test_settings.py                   # 패키지를 테스트하기 위한 환경설정 파일

React

Aiden

Zoe

Gini

Clone this wiki locally