1. modelForm의 사용법
django에서는 폼의 유효성검사 기능을 forms 모듈로 지원하고 있다. forms 중 modelForm은 모델의 필드에 맞추어 그에 맞는 폼형식을 자동으로 생성해주는데, 템플릿단에서 input태그를 하나하나 구현할 필요 없이 {{form.as_태그명}}형식으로 바로 만들어준다.
modelForm을 수정할 경우가 문제인데, 이전에 CRUD수업으로 폼의 인풋태그를 직접 하나하나 만들었던 나로서는 modelForm으로 만들어진 폼에 원래 있던 객체의 정보를 집어 넣는 방법을 몰라 헤맸다.
예를들어,
거래처명 : 피로그래밍
전화번호 : 010-1234-5678
주소 : 서울특별시 관악구 관악로
라는 객체가 이미 저장되어있고, 수정용 페이지를 만들어 이 데이터를 수정하려고 한다고 치자.
수정하려고 할때 원래 글에 있던 내용을 그대로 불러와야 특정 부분을 고쳐 수정할 수 있기 때문에, 원래 있던 글을 입력부분에 그대로 불러오는 방법이 필요하다.
ModelForm에서는 이러한 방식을 인자에 <instance=특정객체> 를 넣음으로써 쉽게 해결 할 수 있도록 해놓았다.
만약 위와 같은 거래처를 수정하는 view함수를 만들고싶다면 아래와 같은 방식으로 만들면 된다.
def update_client(request, pk):
# 수정하려는 특정 객체를 불러와 변수 client에 할당시킨다.
client = Client.objects.get(id=pk)
# 수정페이지로 처음 들어왔을 경우(아직 수정을 완료하지 않았을 경우)
if request.method == "GET":
# ClientForm이라는 모델폼 클래스에 현재 수정할 객체는 client이므로 client의 내용물을 form형태에 넣어 가져오라는 코드
form = ClientForm(instance=client)
return render(request, 'shop/update_client.html' , {
'form': form,
})
# 수정을 완료하고 제출하였을 경우
if request.method == "POST":
# POST방식으로 전달된 form 정보들을 다시 객체의 각 필드에 할당하여 갱신
title = request.POST.get('title')
call_number = request.POST.get('call_number')
address = request.POST.get('address')
client.title = title
client.call_number = call_number
client.address = address
client.save()
return redirect('client_detail', client.id)
2. media 파일 저장 방법
유저에게 form으로 미디어 파일, 예를 들어 사진을 등록받아 저장해두려 한다.
이 경우 POST방식으로 전달되는 부분에는 form태그의 속성에 반드시 enctype=“multipart/form-data”가 들어가야 한다.
<form method="post" action="" enctype="multipart/form-data">
{% csrf_token %}
<ul>
<h2>상품 등록</h2>
#model에 맞는 form을 p태그형태로 템플릿에 나타낸다.
{{ form.as_p }}
<input type="submit" value="등록"/>
</ul>
</form>
여기서 method가 form태그의 전송 방식을 정한다면, enctype은 form 태그로 전달되는 데이터의 형식을 정한다. 설정할 수 있는 enctype 속성의 종류는 다음과 같다.
application/www-form-urlencoded
디폴트 값으로, 모든 데이터를 URL형식으로 인코딩하여 전달한다.
multipart/form-data
파일이나 이미지를 인코딩 하지 않은 상태 그대로 서버에 전달한다.
text/plain
공백은 +기호로 변환되지만, 특수 문자는 인코딩 하지 않은 문자 형식 그대로 전달한다.
파일을 전송할 때 반드시 인코딩하지 않은 ‘multipart/form-data’형식으로 전달해야 하는 이유는 전송 방식과, 데이터 형식에 따른 전송한계 때문이다.
전송 방식에 있어서, GET방식은 데이터를 URL로 전달한다. 이 때 URL은 브라우져에 따라, 클라이언트에 따라 전송 방식의 한계를 가질수도 있다(이전에는 256자,2048자등의 한계가 있었지만 현재 대부분의 브라우져는 URL의 길이제한이 없다고 보는 것이 맞다고 한다). 어찌됐든 데이터 전송 양의 한계 때문에 GET방식이 아닌 POST방식을 사용한다.
POST 방식 내에서도, enctype으로 application/www-form-urlencoded 속성값을 지정하면 파일을 키/값쌍 형식으로 인코딩하여 전달하는데, 전달 용량이 비교적 고용량인 미디어 파일의 전송을 하기에는 용량이 충분하지 않다.
따라서 multipart/form-data를 이용하여 인코딩 하지 않은 파일의 원본을 그대로 보내야만 미디어파일이 정상적으로 업로드되게 되어있다.
이 쯤에서 그렇다면 multipart/form-data를 사용하여 폼을 전송할 때 파일의 용량이 지나치게 큰 경우에 대해 궁금할 수 있다.
기본적으로 POST 전송방식은 HTTP단에서 전송 용량을 제한하지는 않는다. 그러나 해당 프로토콜을 사용하는 브라우저나 서버 단에서 최대 전송량인 maxPostSize 파라미터를 설정해두어 그 크기를 제한하고 있다.
해당 파라미터는 사용자 임의로 변경이 가능하나, 해당 파라미터를 과도하게 키우는 것은 서버로 고용량의 파일이 다수 전송될 경우 서버 과부하의 위험성이 있어 보안공격에 취약해지는 결과를 낳는다.
또, 모든 form에 multipart/form-data 속성값을 설정하는 경우 인코딩이 되지 않은 상태로 전달되기 때문에 일반적으로 같은 데이터라도 전달용량이 커진다. 따라서 반드시 파일을 서버단으로 업로드해야 하는 경우에만 해당 속성값을 적용하는 것이 서버 자원을 낭비하지 않는 방법이다.
3. AJAX로 새로고침 없이 DB 조작하기
간단하게 말해서, 상대의 응답을 기다린 후 다음 작업을 수행하면 동기방식이고, 응답을 기다리지 않고 다음 작업을 수행하면 비동기방식이라고 일컫는다.
동기방식은 한 루틴이 끝나기 전까지 다른 작업을 수행할 수 없으므로 자원을 효과적으로 사용할 수 없지만, 비동기방식은 상대의 응답과는 상관없이 자신의 루틴을 실행하므로 클라이언트가 자료 요청시간(웹으로 치자면 페이지 로딩시간)을 기다릴 필요가 없다.
AJAX는 비동기방식의 자바스크립트로 사용되는 대표적인 기술인데, 플러그인을 따로 설치하지 않고도 사용 가능하며 페이지의 전체 로딩이 아니라 부분로딩이 가능하게 해주므로 성능 개선/ 페이지 이동 최소화 목적으로 주로 사용하고있다.
재고관리사이트 과제 중, 메인페이지(재고리스트페이지)에 있는 재고추가/삭감 버튼을 구현하려고 할 때, 버튼을 post방식으로 만든 후 매번 재고 수량이 갱신된 새 페이지로 이동하게 할 수 있다. 그러나 재고 수량의 변화를 보여주기 위해 페이지의 모든 나머지 부분을 다시 로딩해오는 것은 비효율적이다. 클라이언트의 입장에서도 로딩시간 동안 경험이 단절되므로 불쾌한 사용자 경험을 제공한다고 볼 수 있다. 따라서 페이지의 특정 항목(재고 수량)만을 부분 로딩하기 위해서 AJAX를 사용할 수 있을 것이다.
재고관리 사이트에서 +- 버튼을 통해 유저인터페이스에서 바로 DB를 조작할 수 있는 방법을 찾아보고 있는데, POST방식으로 전체를 다시 로딩해 오는것은 너무 비효율적이라 일부만 재로딩할 수 있는 AJAX 사용법을 배워볼까 했다.
그러나 javascript 문법도 모르는 채로 AJAX에서 특정 모델 필드만 조작하여 새로고침하는 방법을 찾기가 쉽지 않았다. 지인에게 물어보니 ajax를 굳이 사용하지 않더라도 remains가 출력되는 div의 id를 지정하여 재로딩하는 방법을 사용할 수 있다고 했는데, javascript의 load()함수를 사용하면 되는 것 같다. 또, AJAX를 이용하여 템플릿단에서 DB를 조작하는 방식 역시 모델 클래스를 건드려야하는지 감이 잡히지 않았다. 시간 제한이 있는 이번 과제에서는 그냥 새 url을 만들어 전체를 재 로딩하는 방식을 사용하고, 프로젝트를 할 때 AJAX와 JAVASCRIPT관련 기초 지식을 쌓은 후 부분 로딩에 도전해봐야겠다.
'Always Awake > 피로그래밍 12기(19.12.31~20.02.22)' 카테고리의 다른 글
5주차 수요일 팀과제 - 가위바위보 게임 만들기 (0) | 2020.01.31 |
---|---|
피로그래밍 12기 4주차 활동 정리(20.01.21~20.01.27) (0) | 2020.01.27 |
피로그래밍 12기 3주차 활동정리(20.01.14~20.01.20) (0) | 2020.01.20 |
피로그래밍 12기 2주차 활동정리(20.01.07~20.01.13) (0) | 2020.01.13 |
2주차 수요일 개인과제 - bootstrap 사용하여 카피하기 (0) | 2020.01.08 |
댓글