인프런 커뮤니티 질문&답변

김영빈님의 프로필 이미지
김영빈

작성한 질문수

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트

Django Form

form 인스턴스에 대해 질문입니다!

작성

·

158

0

안녕하세요? 강의 잘 듣고 있습니다. 현재 부트캠프에서 이것저것 배우고 있는데, 선생님의 강의를 듣고 갔던게 참 힘이 많이 됩니다ㅎㅎ DRF를 결국 따로 공부해야 할 것 같아서 강의전반을 다시 듣고 있는데 참 많은 내용을 설명해주셨었네요 ㅎㅎ..다시 한번 감사드립니다.
 
의문인 부분이 있는데요
def post_new(request):
    if request.method =="POST":
        form = PostForm(request.POST,request.FILES)
        if form.is_valid():
            post = form.save()
            return redirect(post)
            #get_absolute_url을 찾아감
    else:
        form = PostForm()
       
    return render(request,'instagram/post_form.html',{
        'form':form,
    })
1.위의 코드에서 form = PostForm(request.Post,request.Fiels)일때
이미 form은 마치 어떤 model의 객체(?)와 같이 되어버리는 건가요?
예를 들어,
post = Post.objects.first()
라고 하면 postmodel의 첫번째 객체가 잡히고 , 그 객체의 다른 속성에 접근할 수가 있는데(예를 들어 post.title)
지금 저 form도 방금 예시로 든 post의 상태가 되어버린 건가요??(물론 form에서 구현했고 클라이언트에서 담은 필드에 대한 정보만 담겨져 있겠지만요)
 
2. 유효성 검사 is_valid() 가 통과되면, 유효성 검사가 통과된 값이 자동으로 form.cleaned_data에 데이터가 담기는 것으로 알고 있는데(지난 번에 가르쳐주셔서요!)
 
위의 예시에서 form.save()를 바로 해주는 건, form.save()를 할경우 form.cleaned_data가 연결된 모델에 새로운 데이터로 바로 생성되기 때문에 가능한건가요?
 
한편 24:03초에 post = Post(**form.cleaned_data)라고 post로 받아주는 건, form.claned_data에 담긴 정보를 가진 새로운 post객체를 생성하고 나서 생성된 객체를 post.save()로 저장하려는 의도인건지도 확인을 받고 싶습니다 ㅠㅠ
 
 
 

답변 1

1

이진석님의 프로필 이미지
이진석
지식공유자

안녕하세요.

Post 모델과 PostForm 폼은 별개입니다.

스프링이나 다른 웹프레임워크에서는 웹 요청을 처리할 때 Controller 계층 -> Service 계층 -> Repository 계층으로 나눠서 구현을 하는데요.

현재의 post_new 뷰에서

  1. Controller 계층이 장고에서는 View이고
  2. Service 계층이 PostForm 폼이 되고
  3. Repository 계층이 Post 모델이 됩니다.

PostForm 폼에서는 웹 요청을 실질적으로 처리하는 주체가 됩니다. PostForm을 forms.Form을 상속받아서 하나하나 구현하셔도 되고, Post 모델에 정의된 필드 내역대로 처리하신다면 forms.ModelForm을 상속받아서 모델 폼으로 구현하시면 보다 간결하게 구현하실 수 있습니다.

ModelForm은 장고의 설계철학에 부합되는 효율적인 접근입니다.

https://docs.djangoproject.com/ko/4.0/misc/design-philosophies/#less-code-1

반드시 ModelForm을 써야한다는 것이 아닙니다. Form을 통한 처리도 많이 씁니다. ModelForm을 쓰시는 분들이 반드시 ModelForm을 써야만 장고스러운 처리라고 오해하시는 데 절대 그렇지 않습니다. 경우에 따라 forms.Form을 통한 처리도 좋은 접근입니다.

form = PostForm(request.POST, request.FILES) 코드는

  1. request 객체에서 요청 내역은 .GET, .POST, .FILES 속성을 통해서 접근하실 수 있습니다. 모두 대문자입니다. .Post, .Files 와 같은 이름의 속성은 없습니다.
  2. 위 코드를 통해 현재 요청의 모든 내역을 PostForm에 전달하여 폼 객체를 생성하는 것입니다. Post 모델과는 무관합니다. 폼을 통해 유효성 검사에 통과한 값들을 최종적으로 Post 모델을 통해 DB에 저장하실 수도 있고, DB에 저장없이 이메일 발송을 하실 수도 있고, 구현하기 나름입니다.

장고 Form은 유효성 검사를 진행하는 과정에서 유효성 검사에 통과한 값들을 .cleaned_data 사전 객체에 누적합니다. ModelForm에서는 .save 메서드가 지원되며, Form 에서는 지원되지 않습니다. 제가 24:03에 보여드린 예시는 .save 메서드를 구현한다면 이런 식으로 구현을 해볼 수도 있다라는 예시입니다.

유효성 검사에 통과한 값들로
Post 모델을 통해 새로운 Post 인스턴스를 생성코자 한다면
form.cleaned_data 사전 객체에 유효성 검사에 통과한 값들이 있다고 했을 때

ex) { "title" : "hello title" }

아래와 같이 필드 값을 하나하나 지정하실 수도 있고

post = Post(title=form.cleaned_data["title"])
post.save()

아래와 같이 사전 객체의 unpack 문법을 통해 값들을 한 번에 지정하실 수도 있습니다. 이는 파이썬 기본 문법입니다.

post = Post(**form.cleaned_data)
post.save()

 

화이팅입니다. :-)

 

김영빈님의 프로필 이미지
김영빈

작성한 질문수

질문하기