본문 바로가기

Backend/Django

2022-02-24::Django Forms

Raw HTML form

CSRF verified failed

form 요청할때 머 추가한다.

 

form을 get으로 요청할 때는 검색할 때와 같이 파라미터에 키워드가 추가된 채로 요청을 보낸다.

action에는 요청을 보낼 url을 지정한다.

 

get 요청인 경우 view에 지정된 로직에서

req.GET['{paramName}']

메서드를 통해 파라미터를 받을 수 있다.

get 요청은 보안에 취약하기 때문에 해당 데이터를 저장하는 것은 위험하다

따라서 클라이언트에서 데이터를 전송할 때는 POST 요청을 한다

POST 요청에 담긴 데이터의 경우에는 아래 메서드를 통해 접근이 가능하다

if req.method == "POST":
	req.POST.get('{name}')

위 코드는 데이터는 검증(validation)이 이루어지지 않았기 때문에 위험하다.

Pure Django Form

django에서는 자체적으로 form으로 받은 데이터를 관리 할 수 있다.

먼저 froms.py에 form으로 받을 class를 정의한다.

from django import forms

class RawProductForm(forms.Form):
    title = forms.CharField()
    description = forms.CharField()
    price = forms.DecimalField()

django form fileds를 검색해 더욱 다양한 폼 종류를 확인할 수 있다.

 

다음으로 views.py에 해당 클래스의 인스턴스를 생성한다.

해당 인스턴스를 context로 템플릿에 보낸다.

from .forms import RawProductForm

def product_create_view(req):
    my_form = RawProductForm() #instance 생성
    context = {
        'form': my_form
    }
    return render(req, "product/product_create.html", context)

템플릿에서는 form 인스턴스를 통채로 context로 받았다. 그리고 다음과 같이 사용할 수 있다.

{{form.as_p}}를 통해 위 폼 클래스에 해당하는 html form이 생성된다.

여기서 as_p는 p테그로 각 form을 매핑하겠다는 의미이다.

 

django form을 이용하면 기본적인 validation 기능이 추가되어 있다. 해당 에러들은 또한 클라이언트 화면에 렌더링 된다.

from .models import Product
from .forms import RawProductForm

def product_create_view(req):
    my_form = RawProductForm() #instance 생성
    if req.method == "POST":
        my_form = RawProductForm(req.POST)
        if my_form.is_valid():
            print(my_form.cleaned_data)
            Product.objects.create(**my_form.cleaned_data)
        else:
            print(my_form.errors)

    context = {
        'form': my_form
    }
    return render(req, "product/product_create.html", context)

form instance에 cleaned_data 필드를 통해 dictionary 형태의 깔끔한 데이터를 받을 수 있다. 또한 기존 데이터 생성 방식을 통해 해당 데이터를 DB에 저장할 수 있다. 여기서 **연산자를 통해 자료형을 적절하게 변경해 주어야 한다.

Form Widget

django form field에는 여러가지 여러가지 속성을 부여할 수 있다.

label=''

required= True/False

initital

widget = forms.Textarea(attrs={"class": :"new-class-name two", "rows": 10})

화면에서  큰 사이즈의 input으로 변경

=>widget이라는 attr을 이용해서 렌더링 하는 html form을 통적으로 관리할 수 있다.

Form Validation Methods

django는 내장 검증 기능을 제공한다.

views.py에서 form = ProductionForm(req.POST or None)

POST타입이든 아니든 동적으로 생성

 

forms.py에서 다음과 같이 검증 메서드를 설정할 수 있다.

    def clean_title(self, *args, **kwargs):
        title = self.cleaned_data.get("title")
        if "CFE" in title:
            return title
        else:
            raise forms.ValidationError("This is not a valid ttile")

Initial Values for Forms

사용자가 데이터를 수정하고자 수정 버튼을 누르면 수정 폼은 기존 데이터로 미리 채워져 있어야 한다.

def render_initial_data(req):
    initial_data = {
        'title': "basic title"
    }
    obj = Product.objects().get(id=1)
    form = ProductForm(req.POST or None, instance=obj)
    if form.is_valid():
        form.save()
    context = {
        'form': form
    }
    return render(req, "products/product_create.html", context)

먼저 수정할 데이터를 get()메서드를 통해 가져온 뒤 장고 폼 클래스의 생성자 안에 인스턴스로 넣어준다.

그러면 처음 화면이 렌더링 될 때 가져온 데이터로 폼이 채워진다.

그 이후 POST를 날리면 해당 form의 id가 수정할 데이터의 id로 되어 있기 때문에 데이터를 수정할 수 있다.

 

 

'Backend > Django' 카테고리의 다른 글