[Django] Django Form

Jingi·2024년 3월 28일

Web

목록 보기
12/40
post-thumbnail

Form

HTML 'form'

  • 지금까지 사용자로부터 데이터를 받기위해 활용한 방법 그러나 비정상적 혹은 악의적인 요청을 필터링 할 수 없음 -> 유효한 데이터인지에 대한 확인 필요

유효성 검사

  • 수집한 데이터가 정확하고 유효한지 확인하는 과정

유효성 검사 구현

  • 유효성 검사를 구현하기 위해서는 입력 값, 형식, 중복, 범위,보안 등 많은 것들을 고려해야 함
  • 이런 과정과 기능을 직접 개발하는 것이 아닌 Django가 제공하는 Form을 사용

Form class

Django Form

  • 사용자 입력 데이터를 수집하고, 처리 및 유효성 검사를 수행하기 위한 도구 -> 유효성 검사를 단순화하고 자동화 할 수 있는 기능을 제공
  • 사용자로부터 데이터를 수집하고 처리하기 위한 강력하고 유연한 도구

Form class 정의

class ArticleForm(forms.Form):
    title = forms.CharField(max_length=10)
    content = forms.CharField()
  • Form class를 적용한 new 과정 변화
# views.py
form .forms import ArticleForm
def new(request):
form = ArticleForm()
context = {
    'form': form,
}
return render(request, 'articles/new.html', context)
{% comment %} hew.html {% endcomment %}
<h1>Create</h1>
<form action="{% url "articles:create" %}" method="POST">
  {% csrf_token %}
  {{ form.as_p }}
  <input type = "submit">
</form>
  • .as_p를 하면 p 태그로 묶인다.

Widgets

  • HTML 'input' element의 표현을 담당

Widgets 사용

  • Widget은 단순히 input 요소의 속성 및 출력되는 부분을 변경하는 것
# forms.py
class ArticleForm(forms.Form):
    title = forms.CharField(max_length=10)
    content = forms.CharField(widget=forms.Textarea)

Django ModelForm

  • Form
    • 사용자의 입력 데이터를 DB에 저장하지 않을 때 (ex. 로그인)
  • ModelForm
    • 사용자 입력 데이터를 DB에 저장해야 할 때 (ex. 게시글 작성, 회원가입)
    • Model과 연결된 Form을 자동으로 생성해주는 기능을 제공
      # forms.py
      class ArticleForm(forms.ModelForm):
       class Meta:
           model = Article
           fields = '__all__'

Meta class

  • ModelForm의 정보를 작성하는 것

fields 및 exclude 속성

  • exclude 속성을 사용하여 모델에서 포함하지 않을 필드를 저장할 수도 있음
class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = '__all__'
        exclude = ('title',)

ModelForm을 적용한 create 로직

# views.py
def create(request):
    form = ArticleForm(request.POST)
    if form.is_valid():
        article = form.save()
        return redirect('articles:detail', article.pk)
    return render(request, 'articles/new.html', context)

is_valid()

  • 여러 유효성 검사를 실행하고, 데이터가 유효한지 여부를 Boolean으로 반환
# views.py
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)

ModelForm을 적용한 edit 로직

# views.py
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)
  <h1>EDIT</h1>
  <form action="{% url "articles:update" article.pk %}" method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type = "submit">
  </form>

ModelForm을 적용한 update 로직

# views.py
def update(request, pk):
    article = Article.objects.get(pk=pk)
    form = ArticleForm(request.POST)
    if form.is_valid():
        form.save()
        return redirect('articles:detail', article.pk)
    context = {
        'form': form,
        'article': article,
    }
    return render(request, 'articles/edit.html', context)

save()

  • 데이터베이스 객체를 만들고 저장
  • 메서드가 생성과 수정을 구분하는 방법은 instance를 추가한다.
form = ArticleForm(request.POST, instance=article)

Handling HTTP requests

view 함수 구조 변화

newcreate
데이터 생성을 구현하기 위함데이터 생성을 구현하기 위함
Get method 요청만 처리Post method 요청만 처리
  • new & get 함수 결합
# views.py
def create(request):
    if request.method == 'POST':
        form = ArticleForm(request.POST)
        if form.is_valid():
            article = form.save()
            return redirect('articles:detail', article.pk)
    else:  # POST가 아닌 다른 모든 경우
        form = ArticleForm()
    context = {
        'form': form,
    }
    return render(request, 'articles/create.html', context)
  • upate & edit 결합
# views.py

def update(request, pk):
    article = Article.objects.get(pk=pk)
    if request.method == 'POST':
        form = ArticleForm(request.POST, instance=article)
        if form.is_valid():
            form.save()
            return redirect('articles:detail', article.pk)
    else:
        form = ArticleForm(instance=article)
    context = {
        'form': form,
        'article': article,
    }
    return render(request, 'articles/update.html', context)
profile
데이터 분석에서 백엔드까지...

0개의 댓글