본문 바로가기

프로그래밍/Django

[Django] 폼(Form)에서 commit=False의 의미

form

Commit=False

Django에서 모델 Form을 다루다보면 종종 commit=False라는 코드를 마주칠 때가 있다. 가끔씩 헷갈리는 부분이기 때문에 장고 공식문서를 통해 학습하고자 한다.

save(commit=False) 왜 사용하나요?

스크린샷, 2017-07-29 18-17-34

한줄요약 : commit=False를 하게 되면 데이터베이스에 당장 저장하지 않는다.

언제쓰지? : DB에 데이터를 저장하기 전에 특정 행위를 하고 싶을 때 사용한다..

실제 예제

모델

작성자 모델

idnickname
1사용자1
2사용자2
class Author(models.Model):
    nickname = models.CharField(max_length=20)

간단하게 회원가입할 때 적는 아이디(ID)를 nickname 필드로 지정했다.

게시글 모델

idtitleauthor_id
11번 제목?
22번 제목?
title = models.CharField(max_length=50)
author = models.ForeignKey(Author)

여기서 주목해야 할 점은 ForeignKeyAuthor가 연결됐다는 것이다. 이렇게 연결되면 author_id라는 칼럼이 새로 생기게 된다.
스크린샷, 2017-07-29 18-59-00

진짜 생긴다.. 정말이다.. 이것만 기억하고 ModelForm을 구성해보자

Post 모델을 활용한 모델폼

class PostForm(forms.ModelForm):
 
    class Meta:
        model = Post
 
        fields = [ 
            'title', 
        ]

스크린샷, 2017-07-29 19-00-42
가장 간단한 HTML을 구성했다. 여기서 게시글(post)을 작성하기 위해서는 로그인 한 유저만 할 수 있다는 전제하에 설명을 하도록 하겠다. 로그인 한 유저는 고유의 id값을 갖는다. User모델을 생성할 때 자동으로 생성되는 id값을 의미한다. 만약 save() 메서드에 author_id를 따로 전달하지 않으면 not null 에러 메시지가 발생한다.

스크린샷, 2017-07-29 19-32-22
author가 NULL 값을 허용하지 않기 때문에 어떻게든 작성자의 id를 알아내서 save()메서드에 인자로 넘겨줘야 한다.

save() 메서드를 오버라이드 하자

뷰함수

def post_create(request):
 
    if request.method == "POST":
        form = PostForm(data=request.POST)
        if form.is_valid():
            form.save(author=request.user)

save 메서드에 인자로 author를 넘기고, 현재 유저의 정보를 넘긴다. 노파심에 말하지만 여기서 request.user란 로그인 한 유저를 의미한다.

모델폼

class PostForm(forms.ModelForm):
 
    class Meta:
        model = Post
 
        fields = [ 
            'title', 
        ]
        
def save(self, **kwargs):
    post = super().save(commit=False)         # 부몽메서드 호출 
    post.author = kwargs.get('author'None)
    post.save()
 
    return post

모델 폼에서 부모의 save()를 오버라이드해보자.

  1. 먼저 super()를 통해 부모가 가지고 있는 save()메서드를 호출한다. 대신 저장을 좀만 늦게 해달라고 부탁하자. 그게 바로 commit=False다.

  1. **kwargs로 넘어온 인자중에 author라는 항목이 있다. post 모델에서 user 모델을 참조하기 위해서는 post.author로 접근이 가능하다.

  1. 이제 역할이 끝났다. post.save()를 해주자.

스크린샷, 2017-07-29 19-48-40

이제 ForeignKey로 연결한 작성자의 아이디를 저장할 수 있다. 이래저래 설명이 길었는데 저장을 늦게 시켜서 사용자가 원하는 추가적인 정보를 저장할 수 있는 것이라고 생각하면 된다.