[django] Django ModelForm : save (commit = False)는 무엇에 사용됩니까?

하위 클래스 save(commit=False)에서 양식 객체를 만들고 양식과 모델을 모두 확인하기 위해 ModelForm실행 하는 대신 왜 사용 is_valid()합니까?

즉, 무엇 save(commit=False)입니까?

괜찮다면 이것이 유용 할 수있는 가상의 상황을 제공 할 수 있습니까?



답변

양식에서 대부분의 모델 데이터를 가져 오지만 일부 null=False필드를 비 양식 데이터 로 채워야 할 때 유용 합니다.

commit = False로 저장하면 모델 객체가 생성되고 추가 데이터를 추가하고 저장할 수 있습니다.

이것은 그 상황의 좋은 예입니다.


답변

여기에 답변이 있습니다 ( docs ).

# Create a form instance with POST data.
>>> f = AuthorForm(request.POST)

# Create, but don't save the new author instance.
>>> new_author = f.save(commit=False)

가장 일반적인 상황은 데이터베이스가 아닌 ‘메모리’에서만 양식에서 인스턴스를 가져 오는 것입니다. 저장하기 전에 몇 가지 사항을 변경해야합니다.

# Modify the author in some way.
>>> new_author.some_field = 'some_value'

# Save the new instance.
>>> new_author.save()


답변

Django 문서에서 :

이 save () 메서드는 True 또는 False를 허용하는 선택적 commit 키워드 인수를 허용합니다. commit = False로 save ()를 호출하면 아직 데이터베이스에 저장되지 않은 객체를 반환합니다.

이 경우 결과 모델 인스턴스에서 save ()를 호출하는 것은 사용자의 몫입니다. 이것은 저장하기 전에 객체에 대한 사용자 정의 처리를 수행하거나 특수 모델 저장 옵션 중 하나를 사용하려는 경우 유용합니다. commit은 기본적으로 True입니다.

save (commit = False)가 모델 인스턴스를 생성하여 반환하는 것 같습니다. 실제로 저장하기 전에 일부 포스트 프로세싱에 깔끔합니다!


답변

“실제 예”로 이메일 주소와 사용자 이름이 항상 동일한 사용자 모델을 고려하면 다음과 같이 ModelForm의 저장 방법을 덮어 쓸 수 있습니다.

class UserForm(forms.ModelForm):
    ...
    def save(self):
        # Sets username to email before saving
        user = super(UserForm, self).save(commit=False)
        user.username = user.email
        user.save()
        return user

commit=False사용자 이름을 이메일 주소로 설정하는 데 사용하지 않았다면 사용자 모델의 저장 방법을 수정하거나 사용자 개체를 두 번 저장해야합니다 (비용이 많이 드는 데이터베이스 작업을 복제 함).


답변

            form = AddAttachmentForm(request.POST, request.FILES)
            if form.is_valid():
                attachment = form.save(commit=False)
                attachment.user = student
                attachment.attacher = self.request.user
                attachment.date_attached = timezone.now()
                attachment.competency = competency
                attachment.filename = request.FILES['attachment'].name
                if attachment.filename.lower().endswith(('.png','jpg','jpeg','.ai','.bmp','.gif','.ico','.psd','.svg','.tiff','.tif')):
                    attachment.file_type = "image"
                if attachment.filename.lower().endswith(('.mp4','.mov','.3g2','.avi','.flv','.h264','.m4v','.mpg','.mpeg','.wmv')):
                    attachment.file_type = "video"
                if attachment.filename.lower().endswith(('.aif','.cda','.mid','.midi','.mp3','.mpa','.ogg','.wav','.wma','.wpl')):
                    attachment.file_type = "audio"
                if attachment.filename.lower().endswith(('.csv','.dif','.ods','.xls','.tsv','.dat','.db','.xml','.xlsx','.xlr')):
                    attachment.file_type = "spreasheet"
                if attachment.filename.lower().endswith(('.doc','.pdf','.rtf','.txt')):
                    attachment.file_type = "text"
                attachment.save()

다음은 save (commit = False) 사용 예입니다. 데이터베이스에 저장하기 전에 사용자가 업로드 한 파일 유형을 확인하고 싶었습니다. 또한 해당 필드가 양식에 없기 때문에 첨부 된 날짜를 얻고 싶었습니다.


답변