Django Web Framework/Django CBV

createview, updateview 사용시 주의사항 - 필수 학습

bluebamus 2021. 6. 30.

https://github.com/bluebamus/django_class_based_web_site

 

bluebamus/django_class_based_web_site

This site was created to understand how to use CBV programming in django. - bluebamus/django_class_based_web_site

github.com

두번째 토이 프로젝트를 완료하면서 맞딱트린 문제점과 해결 사항 정리

 

최대한 다양한 CBV 케이스를 다루고 싶어서 object 상속 후 mixin으로 사용하는 방법을 제외하고

기본적으로 사용할만한 CBV는 거의 다 사용해봤다.

 

물론, 애초 계획한 모든 함수를 overriding 하는 것은 시도해보지 못했다.

돌아가게 만드는 것에 급급했다.

 

문제점에 대해 먼저 정의를 해본다.

 

createview 혹안 updateview 사용시 forms.form을 상속해서 사용하면 에러가 생긴다.

그래서 찾아보니 해당 class를 사용하려면 forms.modelform을 상속받아야 한다.

 

이에 대한 가장 근접한 정보를 제공하는 곳 : 

https://wikidocs.net/6652

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

 

정리하자면, createview에서 model이라는 class 변수를 사용하면 modelform이 자동으로 생성된다.

하지만 유효성 검증 등의 문제로 기존과 다른 코드를 구현해 넣어야 한다면

직접 modelform 작성 후 form_class에 해당 폼의 class 명을 넣어주면 된다.

두 변수 모두 선언해도 무방하다.

 

createview에는 model 속성을 생략할 수 있지만, updateview에서는 model을 꼭 선언해 주어야 한다.

 

아니면 다음과 같은 에러 발생함

 

django.core.exceptions.ImproperlyConfigured: MessageUpdateView is missing a QuerySet. Define MessageUpdateView.model, MessageUpdateView.queryset, or override MessageUpdateView.get_queryset().

 

모델 폼의 주요 메소드 호출 순서

 

Get 요청시 : 

dispatch() > get_context_data() > get_initial()

 

Post 요청시 : 

dispatch() > get_initial() > clean() > form_valid()/form_invalid() > get_success_url()

 

당연하겠지만 get_context_data()는 Post 요청시 동작하지 않는다.

form_valid()는 Get 요청시 동작하지 않는다.

 

두 요청에서 공통된 작업을 하고자 한다면 get_initial() 메소드에서 이용 가능하다.

하지만, 이 메소드는 FormMixin의 메소드이기 때문에 해당 클래스를 상속받은 클래스형 뷰에서만 동작한다.

 

dispatch() 메소드를 오버라이딩 하는것을 추천한다.

 

 

* 정보 추가 - def get_initial(self): 사용 예시

url : https://gist.github.com/baxeico/f641eaf9663f0f4122ea

 

A custom UpdateView to set initial data and save the user profile with a custom group field

A custom UpdateView to set initial data and save the user profile with a custom group field - views.py

gist.github.com

from django.contrib.auth.models import User
from django.views.generic import UpdateView

from .forms import UserProfileForm

class UserProfileUpdateView(UpdateView):
    model = User
    
    def get_initial(self):
        initial = super(UserProfileUpdateView, self).get_initial()
        try:
            current_group = self.object.groups.get()
        except:
            # exception can occur if the edited user has no groups
            # or has more than one group
            pass
        else:
            initial['group'] = current_group.pk
        return initial
    
    def get_form_class(self):
        return UserProfileForm
    
    def form_valid(self, form):
        self.object.groups.clear()
        self.object.groups.add(form.cleaned_data['group'])
        return super(UserProfileUpdateView, self).form_valid(form)

댓글