form

Shin Woohyun·2021년 7월 9일
0

form으로 post 방법

add.html

{% extends "tasks/layout.html" %}

{% block body %}
    <h1>Add Task</h1>
    <form action="{% url 'tasks:add' %}" method="post">
        <input type="text" name="task">
        <input type="submit">
    </form>
    <a href="{% url 'tasks:index' %}">View Tasks</a>
{% endblock %}

403 Forbidden -> CSRF verification failed.

  • CSRF : Cross-Site Request Forgery, 웹사이트 취약점 공격의 하나로, 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위(수정, 삭제, 등록 등)를 특정 웹사이트에 요청하게 하는 공격을 말한다.
    -> {% csrf_token %}으로 장고는 편하게 token을 넣을 수 있다. settings.py의 middleware에 'django.middleware.csrf.CsrfViewMiddleware'가 있다.
{% extends "tasks/layout.html" %}

{% block body %}
    <h1>Add Task</h1>
    <form action="{% url 'tasks:add' %}" method="post">
        {% csrf_token %}
        <input type="text" name="task">
        <input type="submit">
    </form>
    <a href="{% url 'tasks:index' %}">View Tasks</a>
{% endblock %}

페이지 소스를 보면 csrfmiddlewaretoken이 생성되어 온 것을 알 수 있다.
<input type="hidden" name="csrfmiddlewaretoken" value="ZQC66Z2uaM5N0SttAsRHfA43aiLFpYM6bcW6kEKaMJD8H8dL0jyAY6gGwGQiIOVh">

make form alternative

views.py

from django.shortcuts import render
from django import forms

class NewTaskForm(forms.Form):
    task = forms.CharField(label="New Task")
    priority = forms.IntegerField(label="Priority", min_value=1, max_value=10)

def add(request):
    return render(request, "tasks/add.html", {
        "form": NewTaskForm()
    })

add.html에 <input type="text" name="task">대신 {{ form }}을 넣는다.
client-side validation - New Task form에 아무것도 입력하지 않거나, priority에 11과 같은 조건에 맞지 않는 값을 넣으면 경고가 뜨면서 실행되지 않는다.

form을 받아서 tasks에 넣기

from django.shortcuts import render
from django import forms
from django.http import HttpResponseRedirect
from django.urls import reverse

tasks = []

class NewTaskForm(forms.Form):
    task = forms.CharField(label="New Task")

def index(request):
    return render(request, "tasks/index.html", {
        "tasks": tasks
    })

def add(request):
    if request.method == "POST":
        form = NewTaskForm(request.POST)
        if form.is_valid():
            task = form.cleaned_data["task"]
            tasks.append(task)
            return HttpResponseRedirect(reverse("tasks:index"))
        else:
            return render(request, "tasks/add.html", {
                "form":form
            })

    return render(request, "tasks/add.html", {
        "form": NewTaskForm()
    })

1.request의 method가 post면, data를 form에 넣고, form이 유효하면 task에 해당하는 값만 tasks에 넣는다. 유효하지 않다면 다시 form을 보내서 뭐가 잘 못 된 것인지 확인할 수 있게 하고, method가 post가 아니라면 tasks/add.html+빈 form을 렌더링한다.
2. HttpResponseRedirect, reverse를 import해서 (url-name으로) index로 리다이렉트 되게끔 한다.
-> index.html이 사용자가 작성한 task를 보여준다. 그런데 tasks가 앱 전역으로 지정되어 있어서 다른 사용자(다른 브라우저 같은)에게도 같은 tasks가 보여진다.

0개의 댓글