Django Form
HTML Form
지금까지 사용자로부터 데이터를 받기위해 활용한 방법
But 비정상적 혹은 악의적인 요청을 필터링 할 수 없음
⇒ 유효한 데이터인지에 대한 확인이 필요
유효성 검사 :
- 수집한 데이터가 정확하고 유효한지 확인하는 과정
- 구현하기엔 많은 것을 고려해야 됨
- ⇒ Django가 제공하는 Form을 쓰겠다.
Django Form
사용자 입력 데이터를 수집하고, 처리 및 유효성 검사를 수행하기 위한 도구
⇒ 유효성 검사를 단순화하고 자동화 할 수 있는 기능을 제공
# apps_name/forms.py
from Django import forms
class ArticleForm(forms,Form):
title = forms.CharField(max_length=10)
content = forms.CharField()
form 태그에서는 TextField가 없음
⇒ 그래서 CharField에서 씀
⇒ max_length를 필수가 아님 == model과의 차이점
<form action="{% url "articles:create" %}" method="POST">
{% csrf_token %}
<div>
<label for="title">Title: </label>
<input type="text" name="title" id="title">
</div>
<div>
<label for="content">Content: </label>
<textarea name="content" id="content"></textarea>
</div>
<input type="submit">
</form>
<!-- 바꾸기 -->
<form action="{% url "articles:create" %}" method="POST">
{% csrf_token %}
{{form}}
<input type="submit">
</form>
Form rendering options
HTML 태그로 label, input 쌍을 감싸는 옵션
form.as_div , as_table ,as_p ,as_ul
Widgets
HTML ‘input’ element의 표현을 담당
Widget은 단순히 input 요소의 속성 및 출력되는 부분을 변경하는 것
[forms.py](<http://forms.py>) 에서 설정 하는 것
# froms.py
content = forms.CharField(widget=forms.Textarea)
Django ModelForm
-Form : 사용자 입력 데이터를 DB에 저장하지 않을 때 ex) 로그인
-ModelForm : 저장해야 할 때 ex) 회원가입, 게시글 작성
ModelForm
Model과 연결된 Form을 자동으로 생성해주는 기능을 제공
Form + Model
# articles/forms.py
from django import forms
from .models import Articles
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = '__all__'
필수요소 2개
- model : 어떤 모델과 연동할거냐
- fields : 그 모델에서 어떤 필드를 쓸것이냐
Meta Class
ModelForm의 정보를 작성하는 곳
fields 및 exclude 속성
field를 사용해서 모델에서 그것만 포함시키거나 OR exclude 속성을 사용하여 포함하지 않거나
ModelForm을 적용한 create 로직
# articles/view.py
# 기존, 유효성 검사가 안이루어짐
def create(request):
title = request.POST.get('title')
content = request.POST.get('content')
article = Article(title=title, content=content)
article.save()
return redirect('articles:detail', article.pk)
# 변경
def create(request):
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save()
return redirect('articles:detail', article.pk)
# 유효성 검사를 통과 못했던 폼을 그대로 다시 보여줌 + 에러 메세지
context = {
'form' : form,
}
return render(request, 'articles/new.html', context)
공백 데이터가 유효하지 않은 이유와 에러메시지가 출력되는 과정
- 별도로 명시하지 않았지만 모델 필드에는 기본적으로 빈 값은 허용하지 않는 제약조건이 설정되어있음
- 빈 값은 is_valid()에 의해 False로 평가되고 form 객체에는 그에 맞는 에러 메시지가 포함되어 다음 코드로 진행됨
update
# articles/views.py
def update(request, pk):
article = Article.objects.get(pk=pk)
form = ArticleForm(request.POST, instance=article) # instance로 생성과 업데이트 구분
if form.is_valid():
form.save()
return redirect('articles:detail', article.pk)
context = {
'form': form,
'article':article # 이거 누락하기 쉬움, 누락하면 유효성검사 실패 시 에러페이지로 감
}
return render(request, 'articles/edit.html', context)
Handling HTTP requests
view 함수 구조 변화
new & create view 함수간 공통점과 차이점
공통점 : 데이터 생성을 구현하기 위함
차이점 : new는 GET method 요청만을, create는 POST method 요청만을 처리
def new(request):
form = ArticleForm()
context = {
'form': form
}
return render(request, 'articles/new.html', context)
def create(request):
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save()
return redirect('articles:detail', article.pk)
# 유효성 검사를 통과 못했던 폼을 그대로 다시 보여줌 + 에러메세지
context = {
'form' : form,
}
return render(request, 'articles/new.html', context)
method 차이만 구분해서 합친 것
def create(request):
form = ArticleForm(request.POST)
if request.method == 'POST': # POST로 받았네
if form.is_valid():
article = form.save()
return redirect('articles:detail', article.pk)
else: # GET을 받았네
form = ArticleForm()
# context 가 이구조로 있어야 유효성 검사 실패했을 때 에러메시지가 저장됨
context = {
'form': form
}
return render(request, 'articles/new.html', context)
Edit 과 Update
def edit(request, pk):
article = Article.objects.get(pk=pk)
form = ArticleForm(instance=article)
context = {
'article': article,
'form' : form,
}
return render(request, 'articles/edit.html', context)
def update(request, pk):
article = Article.objects.get(pk=pk)
form = ArticleForm(request.POST, instance=article)
if form.is_valid():
form.save()
return redirect('articles:detail', article.pk)
context = {
'form': form,
'article':article # 이거 누락하기 쉬움
}
return render(request, 'articles/edit.html', context)
작성 순서
else 부터 채워야지 데이터 흐름을 이해했다고 볼 수 있다.
def create(request):
if request.method == 'POST':
pass
else:
pass
Widget 응용
# articles/formcs.py
class ArticleForm(forms.ModelForm):
title = forms.CharField(
lable='제목',
widget=forms.TextInput(
attrs={
'class': 'my-title'
'placeholder': 'Enter the title',
'maxlength':10,
}
),
)
content = forms.CharField(
label='내용',
widget=forms.Textarea(
attrs={
'class':'my-content',
'placeholder':'Enter the content',
'rows':5,
'cols':50,
}
),
error_messages={'required':'내용을 입력해주세요.'}
)
class Meta:
model = Article
fields = '__all__'
응용 2번째
class TodoForm(forms.ModelForm):
# is_completed = forms.BooleanField(
# widget=forms.HiddenInput(),
# required=False
# )
class Meta:
model = Todo
fields = '__all__'
widgets = {'is_completed':forms.HiddenInput()}
'TIl' 카테고리의 다른 글
Authentication (0) | 2024.04.16 |
---|---|
Statics (1) | 2024.04.16 |
ORM with View (0) | 2024.04.01 |
ORM (0) | 2024.04.01 |
MST, Dijkstra (0) | 2024.04.01 |