Django ModelForm이란?
2022. 1. 19. 12:34ㆍ강의 정리/Django Form
반응형
장고(Django)를 배우기 시작한 입문자이시거나, 또는 배우고 싶은 생각이 있으신 분은 위 출처의 강의를 적극 추천드립니다!!!
ModelForm
- 장고 Form을 상속
- 지정된 Model로부터 필드정보를 읽어들여, Form Field를 세팅
- 내부적으로 Model 객체를 유지
- 유효성 검증에 통과한 값들로, 지정 Model 객체로의 저장을 지원함
#instagram/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = '__all__'
원래 Form을 그냥 만들 때에는 validators를 직접 필드에 지정했어야 했다. 즉 Model에도 지정을 해주어야하고, Form에도 지정을 해줘야하는데 그러면 로직이 분산되므로 관리하기가 매우 힘들다.
이 때
Model Form을 사용하면 Model단에 validators를 구현하게 되면, 자동으로 Form에도 validators 가져와진다.
우리는 Model Form을 사용함으로서 Model단에서만 validators를 지정하면 된다!!!
ModelForm.save(commit=True)
- Form의 cleaned_data(is_valid()를 통해서 유효한 데이터들이 저장된 변수)를 Model 객체(instance) 생성에 사용하고, 그 객체를 리턴
- commit=True #디폴트 값
- model 객체의 save() 및 form.save_m2m()#many to many을 호출
- form.save() != instance.save()
- commit=False
- instance.save() 함수 호출을 지연시키고자할 때 사용
따라서 form.save()를 사용 시 자동적으로 DB에 내용이 저장되고 반영됩니다.
여기서 DB 저장 여부를 commit=True, False와 같은 flag를 통해 지정해줄 수 있습니다.
commit=False는 DB에 반영하지 않는 것을 의미합니다.
#instagram/views.py
def post_new(request):
"""
중략
"""
post = form.save()
"""
중략
"""
return render(request, 'instagram/post_form.html',{
'form' : form,
})
ModelForm.save(commit=False) 예시
- 새 포스팅시 작성자를 고르지않고 싶을 때
https://whatisthenext.tistory.com/131
#instagram/views.py
@login_required
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()
# post의 detail.html로 이동함.
return redirect(post)
else:
form = PostForm()
return render(request, 'instagram/post_form.html',{
'form' : form,
})
- 위 코드 프로세스
- is_valid()를 통해서 유효성 검사를 통과하였다면
- model instance(=post)의 author를 현재 로그인한(request한) User로 설정한다.
- 그후 model instance(=post)를 저장한다.
- 이 때 중요한 것은 위 과정은 필히 로그인이 되어있다는 인증을 받은 후 진행되어야 하기에 장식자로 @login_required를 적어줌
- https://docs.djangoproject.com/en/4.0/ref/request-response/
- 위 주소를 통해서 request 받을 때의 request 측(USER)의 정보를 받을 수 있는 META들을 알수있다.
- EX) REMOTE_ADDR -> 유저의 IP 주소를 알 수 있다.
@login_required
def post_new(request):
"""
중략
"""
if form.is_valid():
comment = form.save(commit=False)
comment.ip = request.META['REMOTE_ADDR'] # IP를 기록하고 save()
"""
중략
"""
return render(request, 'instagram/post_form.html',{
'form' : form,
})
- 참고로 IP주소는 model 필드에
models.GenericIPAddressField 가 존재한다.
#instagram/forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [
'message', 'photo', 'tag_set', 'is_public'
]
- 작성자만 글을 수정하게 만들려면???
if post.author != request.user:
messages.error(request, '작성자만 수정 가능합니다!')
return redirect(post)
View에서의 ModelForm 처리 (New, 새로운 것 생성)
#instagram/views.py
from .forms import PostForm
from .models import Post
def post_new(request):
if request.method == 'POST':
form = PostForm(request.POST, request.FILES)
if form.is_valid():
post = form.save()
# post의 detail.html로 이동함.
return redirect(post)
else:
form = PostForm()
return render(request, 'instagram/post_form.html',{
'form' : form,
})
View에서의 ModelForm 처리 (Edit, 수정하기)
#instagram/views.py
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == 'POST':
form = PostForm(request.POST, request.FILES, instance=post)
if form.is_valid():
post = form.save()
# post의 detail.html로 이동함.
return redirect(post)
else:
form = PostForm(instance=post)
return render(request, 'instagram/post_form.html',{
'form' : form,
})
- get_object_or_404() 함수는 Django 모델을 첫번째 인자로 받고, 몇개의 키워드 인수를 모델 관리자의 get() 함수에 넘깁니다. 만약 객체가 존재하지 않을 경우, Http404 예외가 발생합니다.
폼 인스턴스 데이터에 접근시 cleaned_data를 통해서 접근해야한다.
올바른 예시
form = CommentForm(request.POST)
messages = form.cleaned_data['message']
틀린 예시
form = CommentForm(request.POST)
messages = request.POST['messages']
도움 받은 문서
- https://eveningdev.tistory.com/34
- https://junlab.tistory.com/193
- https://docs.djangoproject.com/ko/4.0/intro/tutorial03/
반응형
'강의 정리 > Django Form' 카테고리의 다른 글
Django Messages Framework (0) | 2022.01.24 |
---|---|
Django Form Validation (0) | 2022.01.19 |
Django Cross Site Request Forgery이란??? (0) | 2022.01.18 |
Django를 더 Django스럽게 만들어주는 Form (0) | 2022.01.18 |
HttpRequest, HttpResponse, JsonResponse (0) | 2022.01.17 |