한 걸음씩

[Django] Form 본문

Django

[Django] Form

winter17 2023. 4. 3. 09:54

1.  개요

  • HTML form
    • 사용자로부터 form 요소를 통해 데이터를 받고 있으나 비정상적 혹은 악의적인 요청을 확인하지 않고 모두 수용중
    • 우리가 원하는 데이터 형식이 맞는지에 대한 '유효성 검증'이 필요
  • 유효성 검사
    • 수집한 데이터가 정확하고 유효한지 확인하는 과정
    • 유효성 검증에는 입력 값, 형식, 중복, 범위, 보안 등 부가적인 많은 것들을 고려해야 함
    • 이런 과정과 기능을 제공해주는 도구가 필요

2.  django Form

  • 사용자 입력 데이터를 수집하고, 처리 및 유효성 검증을 수행하기 위한 도구
  • 유효성 검사를 단순화하고 자동화 할 수 있는 기능을 제공
# articles/form.py
from django import forms


class ArticleForm(forms.Form):
    title = forms.CharField(max_length=10)
    content = forms.CharField()
# articles/views.py
from .forms import ArticleForm
def new(request):
    form = ArticleForm()
    context = {
        'form' : form,
        }
    return render(request, 'new.html', context)
# articles/new.html
<body>
  <h1>New</h1>
  <form action="{% url 'articles:create' %}" method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit">
  </form>
</body>

form class 적용 결과 : {{ form }}&nbsp;&rarr; 자동으로 form 생성
form rendering options : {{ form.as_p}}&nbsp;&rarr; 각자가 p태그로 묶임


3.  Widgets

# articles/form.py
from django import forms


class ArticleForm(forms.Form):
    title = forms.CharField(max_length=10)
    content = forms.CharField(widget=forms.Textarea)

⎣ HTML 파일이 아니라 forms.py에서 class로 접근


4.  django ModelForm

  • Form : 사용자 입력 데이터를 DB에 저장하지 않을 때 (ex. 로그인)
  • ModelForm : 사용자 입력 데이터를 DB에 저장해야 할 때 (ex. 회원가입)
# articles/form.py
from django import forms
from .models import Article

# 기존 ArticleForm 클래스 수정
class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = '__all___'

 

 

 

►  Meta class : ModelForm의 정보를 작성하는 곳

 

  • fields 및 exclude 속성
    • exclude 속성을 사용하여 모델에서 포함하지 않을 필드를 지정할 수도 있음
# articles/form.py
from django import forms
from .models import Article

# 기존 ArticleForm 클래스 수정
class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        exclude = ('title',)
  • ModelForm 을 적용한 create 로직
from .forms import ArticleForm
def create(request):
    form = ArticleForm(request, POST)
    if form.is_value():
        article = article.save()
        return redirect('articles:detail', article.pk)
    context = {
        'form' : form,
    }
    return render(request, 'articles/new.html', context)

 is_valid() : 여러 유효성 검사를 실행하고, 데이터가 유효한지 여부를 boolean으로 반환

 

제목 Input에 공백 값을 입력 후 에러 메시지 확인(유효성 검사 결과)

 

  • ModelForm을 적용한 edit 로직
# articles/views.py
def edit(request, article_pk):
    # 수정 페이지(Edit) 입력 요소에 미리 값을 채우기 위한 데이터 조회
    article = Article.objects.get(pk=article_pk)
    form = ArticleForm(instance=article)
    context = {
        'article': article,
        'form', form,
    }

    return render(request, 'articles/edit.html', context)
# edit.html

<form>
    <h1>Edit</h1>
      <form action="{% url 'articles:update' article.pk %}" method="POST">
        {% csrf_token %}
        {{ form.as_p }}
</form>

 

  • ModelForm 을 적용한 update로직
# articles/views.py

def update(request, article_pk):
    article = Article.objects.get(pk=article_pk)
    form = ArticleForm(request.POST, instance=article)
    if form.is_valid():
        article.save()
        return redirect('article:detail', article.pk)
    context = {
        'form': form,
    }

    return render(request, 'articles:detail', context)

 

  • save() : 데이터베이스 객체를 만들고 저장, 키워드 인자 instance 여부를 통해 생성할 지, 수정할 지를 결정
# create
form = ArticleForm(request.POST)
form.save()

# update
form = ArticleForm(request.POST, instance=article)
form.save()

5.  참고

► ModelForm 키워드 인자 data와 instance 살펴보기

 

► Widget 응용

 

 

► Meta class ?

  • 클래스 안에 클래스? 파이썬에서는 inner class 혹은 nested class라고 하는데
  • 파이썬 문법적 개념으로 접근하지 말 것
  • 단순히 모델 정보를 Meta라는 이름의 내부 클래스로 작성하도록 ModelForm의 설계가 이렇게 되어있을 뿐
  • 우리는 ModelForm의 역할과 사용법을 숙지하는데 집중 할 것

 

'Django' 카테고리의 다른 글

[Django] Cookie & Session  (0) 2023.04.04
[Django] Handling HTTP requests  (0) 2023.04.03
[Django] ORM with view 2  (0) 2023.03.30
[Django] ORM with view 실습  (0) 2023.03.29
[Django] ORM with view  (0) 2023.03.29