본문 바로가기

Back-end & Server/Django

[Django] 비 HTML 콘텐츠와 세션

728x90
반응형

Django에는 HTML이 아닌 일반적인 콘텐츠(CSV, PDF, RSS/Atom 신디케이션 피드, Sitemap)를 생성하는 내장 도구가 있음

 

뷰와 MIME 유형

MIME(Multipurpose Internet Mail Extensions)

  • 과거 메일을 보낼 때 ASCII 코드로된 문자만 보낼 수 있던 문제를 해결하여 메일에 ASCII 코드로된 문자 뿐만 아니라 바이너리 파일도 첨부하여 보낼 수 있게한 인코딩 방식
  • 비 ASCII --인코더--> ASCII --메일 전송 --> ASCII --디코더--> 비 ASCII 

 

Django에서 비 HTML 콘텐츠를 반환하는 방법은 바로 HttpResponse 클래스임

  • HttpResponse 클래스로 인스턴스를 만들 때 content_type 인수를 원하는 타입으로 전달하면 됨
  • content_type의 기본 값은 text/html
  • content_type의 값은 IANA에서 관리하는 공식 인터넷 미디어 유형으로 설정할 수 있음 
 

Media Types

 

www.iana.org

 

예시 CSV 제작

1. 파이썬의 csv 모듈을 사용

import csv
from django.http import HttpResponse as HR

def mkCSV1(request):
    response = HR(content_type='text/csv')
    response['Content-Disposition'] = "attachment; filename=test.csv"

    wr = csv.writer(response)
    wr.writerow(['Frist Row','Foo','Bar','Cho'])
    wr.writerow(['Second Row','A','B','C','Testing'])
    
    return response

이 뷰에 접근하게되면 자동으로 뷰 함수에서 만든 csv 파일 다운로드 창이 열리고 Content-Disposition에 설정한 filename 대로 파일 이름이 설정됨

 

2. 템플릿에 바로 보이기

# view
def mkCSV2(request):
    response = HR(content_type='text/csv')
    response['Content-Disposition'] = "attachment; filename=test.csv"

    csv_data = (
        ('Frist Row','Foo','Bar','Cho'),
        ('Second Row','A','B','C','Testing')
    )
    return render(request,'csv2.html',{'data':csv_data})
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>CSV Test</title>
    </head>
    <body>
        <table border="2">
            {% for rows in data %}
            <tr>
                {% for row in rows %}
                <td>{{row}}</td>
                {% endfor %}
            </tr>
            {% endfor %}
        </table>
    </body>
</html>

다른 비 HTML 콘텐츠들도 이렇게 Django에서 사용할 수 있음

 

 

Django의 세션

세션은 보통 사이트에서 로그인이나 장바구니에 물건을 담은 후 페이지를 이동해도 정보가 유지되도록 하는 방법임

 

Django는 익명 세션을 완벽하게 지원함

 

세션 활성화

  • Django의 세션은 미들웨어를 통해 구현됨
  • 설정의 MIDDLEWARE를 편집하고 'django.contrib.sessions.middleware.SessionMiddleware'가 포함되어 있는지 확인해야함
  • 세션을 사용하지 않으려면 MIDDLEWARE에서 SessionMiddleware 행을 제거하고 INSTALLED_APPS에서 'django.contrib.sessions'를 제거하면됨

 

세션 엔진 구성

  • 데이터베이스 기반 세션(Default)
    • 장고는 기본적으로 데이터베이스에 세션을 저장(django.contrib.sessions.models.Session 모델 사용)
    • INSTALLED_APPS 설정에 'django.contrib.sessions'을 추가해햐 함
    • 추가 후 migrate 시 세션 데이터를 저장하는 단일 데이터베이스 테이블을 설치

 

  • 캐시 세션 세션
    • 성능 향상을 위해 사용
    • 캐시를 구성했는지 확인
    • Django는 캐시가 여러 개인 경우 기본 캐시를 사용, 다른 캐시를 사용하려면 SESSION_CACHE_ALIAS를 해당 캐시 이름으로 설정해야함

 

간단한 캐싱 세션 스토어 지속적이고 캐시된 데이터의 경우
SESSION ENGINE을
"django.contrib.sessions.backends.cache"로 설정
SESSION ENGINE을
"django.contrib.sessions.backends.cached_db"로 설정
- 세션 데이터는 캐시에 직접 저장됨
- 세션 데이터가 지속되지 않을 수 있음
- 캐시가 가득차거나 캐시 서버가 다시 시작되면 캐시된 데이터가 제거될 수 있음
- 캐시를 통한 쓰기 기능 사용
- 캐시에 대한 모든 쓰기도 데이터베이스에 기록
- 세션 읽기는 데이터가 캐시에 없는 경우에만 데이터베이스를 사용

 

  • 파일 기반 세션
    • SESSION ENGINE을 "django.contrib.sessions.backends.file"로 설정해야함
    • Django가 세션 파일을 저장하는 곳을 제어하기 위해 SESSION_FILE_PATH를 설정할 수도 잇음
    • 웹 서버에 이 위치를 읽고 쓸 수 있는 권한이 있는지 확인

 

  • 쿠키 기반 세션
    • SESSION_ENGINE을 "django.contrib.sessions.backends.signed_cookies"로 설정해야함
    • 세션 데이터는 장고의 암호화 서명 도구SECRET_KEY 설정을 사용해 저장됨
    • Javascript에 저장된 데이터에 액세스하지 못하게 하려면 SESSION_COOKIE_HTTPONLY 설정을 True로 하는 것이 좋음

 

뷰에서 세션 사용

SessionMiddleware가 활성화되면 각 HttpRequest 객체는 딕셔너리와 유사한 객체인 session 속성을 가짐

 

request.session을 읽고 쓸 수 있음

 

모든 세션 객체는 기본 클래스 backends.base.SessionBase에 상속됨

이 클래스는 다음과 같은 표준 딕셔너리 메서드를 가짐(dir(request.session)을 통해 더 많은 속성들 확인 가능)

 

__getitem__(key) key 값에 해당하는 세션 값을 가져옴

ex. fav_color = request.session['fav_color']
__setitem__(key,value) key 값에 해당하는 세션의 값을 value로 설정

ex. request.session['fav_color'] = blue
__delitem__(key) key 값에 해당하는 세션을 삭제

ex. del request.session['fav_color']
__contains__(key) key가 세션에 존재하는지 확인

ex. 'fav_color' in request.session
get(key,default=None) key가 세션에 존재하면 값에 해당하는 세션 값을 반환하고 없으면 default에 설정된 값을 반환

ex. fav_color = request.session.get('fav_color','red')
pop(key,default=None) key에 해당하는 세션 값을 pop함, key값이 없는경우 default에 설정된 값을 반환

ex. fav_color = request.session.pop('fav_color','blue')
keys() 세션의 key들을 반환
items() 세션의 key와 value 들을 반환
setdefault(key,default=None) 키가 세션에 있으면 해당 값을 반환, 그렇지 않은 경우 default 값이 있는 키를 삽입하고 default 값을 반환
clear() 세션을 초기화함

 

추가적인 메서드

flush() 세션에서 현재 세션 데이터를 삭제하고 세션 쿠기를 삭제 (django.contrib.auth.logout() 함수가 이를 호출)
set_test_cookie() 사용자의 웹 브라우저가 쿠키를 지원하는지 여부를 결정하는 테스트 쿠키를 설정
test_cookie_worked() 사용자 웹 브라우저가 테스트 쿠키를 수락했는지 여부에 따라 True, False를 반환, 이전의 웹 페이지 요청에서 set_test_cookie()를 호출해야함
delete_test_cookie() 테스트 쿠키를 삭제
set_expiry(값) 세션의 만기 시간 설정

- 값이 정수 : 정수(초) 동안 사용하지 않으면 만료
- 값이 datetime이나 timedelta 객체 : 특정 날짜/시간에 세션이 만료
- 값이 0 : 사용자의 웹 브라우저가 닫힐 때 세션 쿠키가 만료
- 값이 None :  세션은 전역 세션 만료ㅛ 정책을 사용하도록 되돌림
get_expiry_age() 이 세션이 만료될 때까지의 소요 시간을 반환
get_expiry_date() 이 세션의 만료되는 날짜를 반환
get_expire_at_browser_close() 사용자의 웹 브라우저가 닫힐 때 사용자의 세션 쿠기가 만료되는지 여부에 따라 True, False를 반환
clear_expired() 세션 스토어에서 만료된 세션을 삭제, clearsessions로 호출
cycle_key() 현재 세션 데이터를 유지허면서 새로운 세션 키를 만듦(django.contrib.auth.login()은 이메서드 호출을 통해 세션 고정을 완화함)

 

세션 예시

def session1(request):
    # set session
    request.session['One'] = "hello1"
    request.session['Two'] = "hello2"
    request.session['Three'] = "hello3"
    
    # 5초뒤 만료
    request.session.set_expiry(5)
    html = f"""<h1>One : {request.session['One']}</h1>
    <h1>Two :{request.session['Two']}</h1>
    <h1>Three : {request.session['Three']}</h1>"""
    return HR(html)

def session2(request):
    # set session
    request.session['Two'] = "hello2"
    request.session['Three'] = {"ao":"hello","bo":"hello"}
    # 일반적인 변경
    request.session['Two'] = "bye..."
    # 명시적 변경
    request.session['Three']['ao'] = 'GoodBye~'
    request.session.modified = True

    two = request.session['Two'] 
    three = request.session['Three']
    return HR(f"<h1>Two : {two}</h1><h1>Three : {three}</h1>")

 

728x90
반응형

'Back-end & Server > Django' 카테고리의 다른 글

[Django] 미들웨어(Middleware)  (0) 2023.02.06
[Django] 캐시 프레임워크  (0) 2023.02.04
[Django] 배포  (0) 2023.01.31
[Django] 테스팅  (0) 2023.01.22
[Django] 고급 기능들  (0) 2023.01.20