이 글은 formset, is_valid 에 대한 공부 및 정리 목적으로 쓰는 글이다.
1. formset 이란 무엇인가?
여러개의 폼을 한번에 처리 하는데 사용 된다.
Formset은 동일한 폼 클래스를 사용하여 여러 개의 인스턴스를 생성하고, 이 들을 한번에 처리하고 저장 하도록 도와준다.
ex) 여러개의 댓글을 동시에 작성 하거나, 한번에 여러개의 파일을 업로드 할 경, Formset를 이용 하면 된다.
# forms.py
from django import forms
from django.forms import formset_factory
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('name', 'email', 'message')
CommentFormSet = formset_factory(CommentForm, extra=3) # 최대 3개의 댓글을 작성할 수 있는 Formset을 생성한.
# views.py
from django.shortcuts import render
from .forms import CommentFormSet
def add_comment(request):
if request.method == 'POST':
formset = CommentFormSet(request.POST)
if formset.is_valid():
formset.save() # 모든 댓글을 한 번에 저장합니다.
else:
formset = CommentFormSet()
return render(request, 'add_comment.html', {'formset': formset})
# add_comment.html
<form method="post">
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.as_p }}
{% endfor %}
<button type="submit">저장하기</button>
</form>
2. is_valid() 이란 무엇인가?
사용자가 제출한 데이터가 유효한지 여부를 검증 한다.
이 메서드는 사용자 입력 데이터를 유효성 검사하고, 검증에 실패한 필드에 대한 오류를 포함한 폼 에러를 생성한다.
is_valid() 들은 많은 하위 함수들을 호출 하여 작동하는 함수이다.
하위 함수 들은 이렇게 존재 한다.
1. full_clean(): is_valid() 가 호출 되면 먼저 full_clean() 메서드가 호출 되고, 이 메서드 에서는 폼의 각 필드에 대해
clean() 메서드 와 clean_<fieldname>() 메서드를 차례로 호출 한다.
full_clean() 메서드는 ValidationError 예외를 발생 시키고, 이러한 예외는 폼의 에러 리스트에 추가 한다.
2. clean(): clean() 메서드는 전체 폼에 대한 유효성 검사를 수행한다.
이 메서드는 폼의 모든 필드에 대해 유효성 검사를 수행하고, 모든 필드에서 통과한 후에만 폼 전체에서 통과한다.
이 메서드는 일반적으로 여러 필드를 조합 하여 검증 규칙을 정의하고 필드 간의 관계를 검사한다.
예를 들면 이러한 코드이다.
from django import forms
class ContactForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
def clean(self):
cleaned_data = super().clean()
name = cleaned_data.get('name')
email = cleaned_data.get('email')
message = cleaned_data.get('message')
if not name and not email and not message:
raise forms.ValidationError('You have to write something!')
위의 코드에서 clean() 메서드는 'name', 'email', 'message' 필드를 검사 하고, 이들 필드 중 하나 라도 입력 되지 않았을때
ValidationError 예외를 발생 시킨다.
3. clean_<fieldname>(): clean_<fieldname>() 메서드는 특정 필드에 대한 유효성 검사를 수행 한다.
이 메서드는 해당 필드에서 유효성 검사를 수행 하며, 필드에서 통과한 경우 cleaned_data 딕셔너리에 저장 된다.
이 메서드는 필드 별 검 증 규칙을 정의 할 수 있다.
from django import forms
class ContactForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
def clean_name(self):
name = self.cleaned_data.get('name')
if name == 'Admin':
raise forms.ValidationError("Admin is not a valid name.")
return name
위의 코드에 'cleaned_name()` 메서드는 'name' 필드를 검사하고, 입력된 값이 admin 일 경우 ValidationError 예외를 발생 시키고, 만약 검증에 통과한다면, 해당 필의 값이 'cleaned_data' 딕셔너리에 저장 된다.
4. validate_unique(): 'validate_unique()' 메서드는 모델 폼에서 사용 되고, 이 메서드는 모델 에서 고유한 필드를 검증 한다.
즉, 중복 검사를 실시 한다고 보면 된다.
5. has_error(fieldname): 이 메서드는 특정 필드에 대한 에러 여부를 확인한다. 에러가 존재하면 True, 반대 라면 False를 반환 한다.
6. errors: 이 속성은 폼에서 발생한 모든 에러를 담고 있는 딕셔너리 이다. 딕셔너리 의 각 키는 에러가 발생한 필드 이름,
값은 에러 메시지 리스트 이다.
is_valid()가 False로 반환된 코드상에서 print(form.errors()) 하면 보일 것이다.
7.'non_field_errors()': 이 메서드는 필드와 관련되지 않은 모든 에러 메시지를 리스트로 반환 한다.
clean() 메서드에서 발생한 에러는 이 메서드를 통해 확인 할수 있다.
8. add_error(field, error): 이 메서드는 특정 필드에 대한 에러 메시지를 추가 한다.
필드 와 에러메시지를 인수로 전달 해야 한다.
ex)
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
def clean(self):
cleaned_data = super().clean()
name = cleaned_data.get('name')
email = cleaned_data.get('email')
message = cleaned_data.get('message')
if not name:
self.add_error('name', '이름을 입력해주세요.')
if not email:
self.add_error('email', '이메일을 입력해주세요.')
if not message:
self.add_error('message', '메시지를 입력해주세요.')
form = ContactForm(data={'name': '', 'email': '', 'message': ''})
form.is_valid()
print(form.errors)
{'name': ['이름을 입력해주세요.'], 'email': ['이메일을 입력해주세요.'], 'message': ['메시지를 입력해주세요.']}
9. add_waring(field, warning): 이 메서드는 특정 필드 에 대한 경고 메시지를 추가 하는 메서드 이다.
필드 와 경고 메시지를 인수로 전달 해야 하며, 경고 메시지는 에러 메시지와 달리, 폼 유효성 검사를 실패하지 않도록 허용 한다.
ex)
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea)
def clean(self):
cleaned_data = super().clean()
message = cleaned_data.get('message')
if message and len(message) < 10:
self.add_warning('message', '메시지가 너무 짧습니다.')
form = ContactForm(data={'name': '홍길동', 'email': 'hong@example.com', 'message': '안녕하세요.'})
form.is_valid()
form.add_warning('name', '이름이 너무 짧습니다.')
print(form.errors)
print(form.warnings)
{}
{'name': ['이름이 너무 짧습니다.'], 'message': ['메시지가 너무 짧습니다.']}
'Python' 카테고리의 다른 글
파이썬으로 어셈블리어 공부하기 (0) | 2023.05.27 |
---|---|
aiohttp로 하는 비동기 HTTP 요청 (0) | 2023.05.13 |
UUID란? (0) | 2023.05.05 |
딕셔너리에서 value 와 key 활용하여 정렬 하기 (0) | 2023.04.15 |
[Python] DataFrame 의 결측값, 중복값 확인하고 제거 (0) | 2023.04.12 |