Django

Django Form, Django Model Form

zhelddustmq 2024. 8. 16. 13:03

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)
...

(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

 

Creating forms from models | Django documentation

The web framework for perfectionists with deadlines.

docs.djangoproject.com

 

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