01. Django Form Class
02. Django Model Form Class
01. Django Form Class: django는 일부 반복되는 작업과 코드를 줄일 수 있는 django form을 제공(form, view, 유효성 등)
디테일한 부분 구현이 필요하다면 직접 구현하는게 좋음.
Form 선언
# articles/forms.py
from django import forms
class ArticleForm(forms.Form):
title = forms.CharField(max_length=10)
content = forms.CharField()
Model 선언과 비슷하게 Form에서 입력받고자 하는 데이터에 대한 명세를 작성
→ 형식이나 속성도 일부 Model과 비슷
Form 적용하기
# articles/new.html
...
{{ form.as_p }}
...
# articles/views.py
from.forms import ArticleForm
...
def new(request):
form = ArticleForm()
context = {
"form": form,
}
return render(request, "new.html", context)
...
- Form rendering options: label과 input을 랜더링하는것에 대한 옵션
공식문서: https://docs.djangoproject.com/en/4.2/topics/forms/#form-rendering-options
- as_div : <div>로 감싸져서 렌더링
- as_p : <p>로 감싸져서 렌더링
- Form Widget: 웹 페이지에서 Form Input 요소가 어떻게 렌더링 되어서 보여질지 정의
공식문서: https://docs.djangoproject.com/en/4.2/topics/forms/#widgets
Form Fields에 할당해서 사용
=> <input type=”text”> 에 썼던 것
(text field)
(choice field: 카테고리)
from django import forms
class ArticleForm(forms.Form):
# 앞은 데이터베이스에 저장될 값, 뒤는 사용자에게 보여질 값
GENRE_CHOICES = [
("technology", "Technology"),
("life", "Life"),
("hobby", "Hobby"),
]
title = forms.CharField(max_length=10)
content = forms.CharField(widget=forms.Textarea)
genre = forms.ChoiceField(choices=GENRE_CHOICES)
02. Django Model Form Class: Django Form과 Model이 유사. 그래서 Django가 알아서 Model을 참조해 Model Field를 보고 Form을 만들어 줌
공식문서: https://docs.djangoproject.com/en/4.2/topics/forms/modelforms/#modelform
Model을 통해서 Form Class를 만드는 방식
# articles/forms.py
from django import forms
from articles.models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = "__all__"
# exclude = ["title"]
- ModelForm이 사용할 데이터를 Meta 클래스에 명시
- fields 항목에 내가 form으로 만들고 싶은 항목들을 지정
view에서 Django ModelForm 사용하기
# articles/views.py
...
def create(request):
form = ArticleForm(request.POST) # form에 request.POST에 있는 데이터 채워
if form.is_valid(): # form 형식에 맞으면
article = form.save() # 저장하고 해당 객체 반환
return redirect("article_detail", article.id)
return redirect("new")
...
현재의 new 함수와 create 함수가 많이 흡사
def new(request):
form = ArticleForm()
context = {
"form": form,
}
return render(request, "new.html", context)
⇒ 그냥 create 함수 하나로 처리하자!
- GET으로 들어오면 비어있는 Form 보여주고, POST로 들어오면 데이터 채워서 보낸거니까 새로운 article 생성하면 됨
new - create 수정하기
def create(request):
if request.method == "POST":
form = ArticleForm(request.POST)
if form.is_valid():
article = form.save()
return redirect("article_detail", article.id)
else:
form = ArticleForm()
context = {"form": form}
return render(request, "create.html", context)
new 라는 구조가 필요없음!!
- new view 함수 지우기
- new url path 지우기
- new.html을 create.html 로 변경
# create.html (전 new.html)
{% extends "base.html" %}
{% block content %}
<h1>New Article</h1>
<form action="{% url 'create' %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">저장</button>
</form>
{% endblock content %}
articles.html 에서 새 글 작성을 create 로 변경
edit - update 수정하기
- edit과 update도 마찬가지로 아래의 로직으로 처리가 가능
- GET으로 수정하기에 요청이 들어오면, 데이터 채운 Form을 랜더링해서 보여줌.
- POST로 수정하기에 요청이 들어오면, 새로운 데이터가 들어오는거니까 수정으로 처리
def update(request, pk):
article = Article.objects.get(pk=pk)
if request.method == "POST":
form = ArticleForm(request.POST, instance=article)
if form.is_valid():
article = form.save()
return redirect("article_detail", article.pk)
else:
form = ArticleForm(instance=article)
context = {
"form": form,
"article": article,
}
return render(request, "update.html", context)
※ Model Form은 instance라는 속성에 값이 있으면 해당 instance를 수정하고 값이 없으면 새로 생성하는 로직을 수행
- 마찬가지로 이제 edit 구조가 필요없음
- edit view를 지우기
- edit url path 지우기
- edit.html을 update.html로 변경
# update.html (전 edit.html)
{% extends "base.html" %}
{% block content %}
<h1>Update Article</h1>
<form action="{% url 'update' article.pk %}" method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">수정</button>
</form>
<a href="{% url 'article_detail' article.pk %}">이전으로</a>
{% endblock content %}
- article_detail.html 에서 글 수정 버튼 변경
→ 기존 edit이었던 부분을 update 로 수정
'Django' 카테고리의 다른 글
Auth (0) | 2024.08.17 |
---|---|
URL Namespace / Templates Namespace (Django 플젝 시작 시 유의사항) (0) | 2024.08.16 |
Django MTV 사용하기 (RUD) (0) | 2024.08.14 |
Django MTV 사용하기(CR, DB 조회 역순, CSRF) (0) | 2024.08.14 |
ORM(Django) (0) | 2024.08.14 |