[Django] 장고 Forms를 활용한 효율적인 데이터 유효성 검사 및 저장#2

아직·2022년 7월 8일
1
post-thumbnail

1)

장고의 가장 주목할만한 기능은 model, form, REST framework라고 한다. 여기서 model과 form은 유사한 구성을 갖는데 form은 클라이언트-유저 영역에 집중돼있고, model은 서버-db 영역에 집중돼있다.

model은 "db에 이런식으로 저장할래." 정도로 생각하면 되는데 form을 model에 맞춰 설계하는 경우가 많다.

이는 유지-보수에서 번거로운 작업일 수 있는데, 그래서 나온 것이 model-form이다. MF는 model의 필드 정보를 가져와서 form field를 생성하는데 도움을 준다.

post_form.html, views.py에서도 form과 관련한 많은 양의 코딩을 볼 수 없다. 사실 {{ form }}이 마법의 단어같이 다가왔다. 따라서 models.py를 살찌우는 게 중요한데, model이 풍성하면 REST framework의 model-serializer에서도 수혜를 볼 수 있다고 한다.

2)

폼을 상속하는 경우는 개발자가 '모델에 맞춰' 필드를 요청해야하는 반면, 모델 폼을 상속하는 경우는 지정 모델에 따라 읽어올 필드를 힘들이지 않고 요청할 수 있다.

3)

def post_new(request):
    if request.method == 'POST':
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            post = form.save(commit=False)
            return redirect(post) 

commit의 디폴트 True 값을 False로 바꿔줄 경우, model_instance.save()를 호출하지 않는다. 해당 url로 넘어갈(redirect) 경우 NoReverseMatch 에러가 난 것을 확인할 수 있었다.

form.save라고 적혀있지만, 기능상 post.save에 가까운 것 같다.

def get_absolute_url(self):
        return reverse('instagram:post_detail', args=[self.pk])
+
urlpatterns = [
    path('new/', views.post_new, name='post_new'),
    path('', views.post_list, name='post_list'),
    path('<int:pk>', views.post_detail, name='post_detail'),

인스턴스가 없다면 pk 값은 None이므로 (아래를 참고했을 때) 숫자만 받는 post_detail이 reverse를 수행할 수 없기 때문이다.

4)

@login_required # request.user를 외래키로 할당하려면 로그인 상태라는 보증이 필요하니까
def post_new(request):
    if request.method == 'POST':
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user # 현재 로그인 유저 instance
            post.save()
            return redirect(post)  

흐름상 author를 선택하는 부분은 말이 안되기 때문에 forms.py의 __all__ 대신 author를 제외한 필드를 선택해주었다. 그러나 models.py의 Post 클래스에서 blank를 허용한다는 부분이 없으므로 IntegrityError가 발생했다.

여기서 commit=False를 활용할 수 있었다. model instance의 생성을 유예하고 author를 request.user로 할당한 뒤 post.save() 작업을 거쳐서 IntegrityError를 해결했다.

이 때 보안을 위해서 로그인 장식자를 활용한 점을 주목하자.

0개의 댓글