ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 장고 Forms를 활용한 효율적인 데이터 유효성 검사 및 저장
    카테고리 없음 2021. 11. 1. 13:58

    <HTML Form>

    HTML Form (클라이언트 측) : 클라이언트에서 사용자에게 입력폼을 제공하고, 이를 서버로 전송하고자 할 때.

    Django Form (서버 측) : 클라이언트로부터 전달받은 값들에 대한 유효성 검사를 수행하고, 이를 데이터베이스에 저장하는 등의 처리 

     

    <form action="" method="POST">

      <input type="text" />            : 1줄 문자열 입력

      <textarea></textarea>          : 1줄 이상의 문자열 이비력

      <select></select>                 : 항목 중 택일

      <input type="checkbox"/>   : 체크박스

      <input type="radio"/>           : 라디오박스

    </form>

     

    <HTML <form> 태그 필수 속성 >

    1. action : 요청을 보낼 주소 

    2. method : 전송 방식 

     - "GET": 주로 데이터 조회 요청 시에 사용

     - "POST" : 파괴적인 액션(생성/삭제/수정)에서 사용

    3. enctype : 인코딩 방식 

     - GET 요청에서는 한 enctype으로 강제됨.

     - POST 요청에서만 유효. 파일등 다양한 소스를 넣는다면 enctype = "multipart/form-data"

     

    <Form 요청에서 인자 보내는 2가지 방법>

    1) 요청 URL 뒤에 ?를 붙이고, 인자를 실어서 보내기

    - Query String 인자라고 부른다.   

    2) 요청 body에 모든 인코딩의 인자를 실어서 보내기 

     

    <2가지 Form Method>

    GET 방식

    - 엽서에 비유, 물건을 보낼 수 없다. 

    - application/x-www-form-urlencoded 만이 강제되며, 인코딩된 문자열을 QueryString으로 전달 

    POST 방식 

    - 택배에 비유. 다양한 물건을 보낼 수 있다. 

    - 다양한 인코딩을 모두 사용 가능하며, 인코딩된 데이터를 "요청 Body"에 담아서 전달 

     

    # post에 파일 업로드를 수행한다면, enctype = "multipart/form-data" 를 꼭 넣어주어야 한다. 

     

    <HttpRequest(요청)와 HttpResponse(응답)>

    HttpRequest 객체 

    클라이언트로부터의 모든 요청 내용을 담고 있으며,

    - 함수 기반 뷰: 매 요청 시마다 뷰 함수의 첫번째 인자 request로 전달 

    - 클래스 기반 뷰: 매 요청 시마다 self.request를 통해 접근 

    Form 처리 관련 속성들 

     .method : 요청의 종류 "GET" or "POST"

     .GET : GET 인자 목록 (QueryDict 타입. key 중복 허용)

     .POST : POST 인자 목록 (QueryDict 타입. key 중복 허용)

     .FILES : POST 인자 중에서 파일 목록 

     

    MultiValueDict 

    - dict를 상속받은 클래스. 동일 key의 다수 value를 지원하는 사전

    - 수정 불가능한 특성 

     

    <DjangoForm>

    장고를 사용함에 있어서 가장 중요한 것은 Form 

     

    Model: 데이터베이스와의 interaction

    Forms: User의 입력폼과의 interaction

     

    <Django Style의 Form 처리> 

    하나의 URL (하나의 View)에서 2가지 역할을 모두 수행

    1) 빈 폼을 보여주는 역할

    2) 폼을 통해 입력된 값을 검증하고 저장하는 역할

     

    GET 방식으로 요청 받았을 때

    - New/Edit 입력폼을 보여줍니다. 

    POST 방식으로 요청 받았을 때

    - 데이터를 입력받아 유효성 검증 수행

    - 검증 성공 시 : 해당 데이터를 저장하고 SUCCESS URL로 이동

    - 검증 실패 시 : 오류메세지와 함께 입력폼을 다시 보여줍니다.

     

    <form을 사용한 views.py 예시> 

     if request.method == 'POST':  # POST 요청일 때
       form = PostForm(request.POST, request.FILES)
     else: # GET 요청일 때
       form = PostForm()

     

    <modelForm을 사용할 때, forms.py>

    class PostForm (forms.ModelForm):
      class Meta:
        model = Post
        fields = ["필요한 것들..."] or "__all__"

     

    <Cross Siste Request Forgery (CSRF) = 사이트 간 요청 위조 공격>

    사용자가 의도하지 않게 게시판에 글을 작성하거나, 쇼핑을 하게 하는 등의 공격 

     

    공격을 막기 위해 Token을 통한 체크

    - POST 요청에 하해 CsrfViewMiddleware를 통한 체크 => settings의 middleware에 있음 

     

    forms.py에서 POST 요청일 때, {% csrf_token %} 하나만으로 체크가 가능하다

    csrf_token은 현재 인증이 유효한지를 판단

    따라서, 유저인증 Token, JWT와는 다르다! 

     

    <ModelForm>

    Form / ModelForm

     

    <Form을 사용할 때>

    class PostForm(forms.Form):

       title = forms.CharField()

       content = forms.CharField(widget=forms.Textarea)

     

    <ModelForm을 사용할 때> 

    class PostModelForm(forms.ModelForm):

       class Meta:

          model = Post

          fields = ['title', 'content']

     

    => 주로 ModelForm을 사용하자!  하지만, model에서 받아올 것이 없는 form을 만들 때만 그냥 Form을 사용한다. 

     

    save를 함에 있어서 default는 (commit=True) 이다. 보통은 이렇게 많이 쓰지만, form에서 세부 정보를 수정해야 할때는, commit = False로 받고 나머지를 수정한다음 save() 하면 된다. 

     

    forms.py에서

    fields = [이것을 포함하겠다]  ex) '__all__'도 있음

    exclude = [이것을 배제하겠다]

     

    편집과정에서는 instance를 입력해 주면 된다.

    ex). form = PostModelForm(request.POST, request.FILES, instance=post)

     

    <Form Validation>

    Form 유효성 검사가 수행되는 시점

    - form을 지정한 후, 바로 유효성 검사를 시작하고, 모든 유효성(fields)이 통과되면 참으로 반환한다. 

     

    유효성 검사 호출로직 (form.is_valid()호출 당시)

    1. form.full_clean() 호출

      1) 각 필드 객체 별로

      - 각 필드캑체.clean() 호출을 통해 각 필드 Type에 맞춰 유효성 검사

      2) Form 객체 내에서 (forms.py)

      - 필드 이름 별로 Form객체.clean_필드명() 함수가 있다면 호출해서 유효성 검사 => 1개 일 때

      - Form객체.clean() 함수가 있다면 호출해서 유효성 검사 => 여러개 일 때

    2. 에러 유무에 따른 Tue/False 리턴

     

    Form에서 수행하는 2가지 유효성 검사

    1. Validator 함수를 통한 유효성 검사 

    2. Form 클래스 내 clean, clean_ 멤버함수를 통한 유효성 검사 및 값 변경 

     

    언제 validators를 쓰고, 언제 clean을 작성?

    - 가급적이면 모든 validators는 모델에 정의하고, ModelForm을 통해 모델의 validators 정보도 같이 가져오기 

    - clean은 값을 변경할 수 있지만, validators는 값 체크기능만 존재한다. 

    clean이 필요할 때

    - 특정 Form에서 1회성 유효성 검사 루틴이 필여할 때

    - 다수 필드값에 걸쳐서, 유효성 검사가 필요할 때

    - 필드 값을 변경할 필요가 있을 때 

     

    <Messages Framework>

    Messages : admin에서 특정한 action을 처리했을 때, alert 뜨는 것. ex) "저장했습니다",  "로그인 되었습니다"

     

    Message Levels를 통한 메시지 분류 

    레벨의 종류

    - DEBUG : 디폴트 설정으로 무시되는 레벨 

    - INFO : 해당 유저에 대한 정보성 메세지

    - SUCCESS : 액션이 성공적으로 수행되었음을 알림

    - WARNING : 실패가 아직 발생하진 않았지만, 임박했다. 

    - ERROR : 액션이 수행되지 않았거나, 다른 Failure가 발생했다. 

     

    messages 등록 코드

    views.py의 form.is_valid() 안에

      messages.add_message(request, messages.SUCCESS, '새 글이 등록되었습니다.') 또는

      messages.success(request, '새 글이 등록되었습니다.')

     

Designed by Tistory.