● Form

  ① Form 태그를 쉽게 만들 수 있는 기능

  ② 유효성 검사 기능

 

1. ModelForm : Model을 이용한 Form 생성

# forms.py

class NoticeForm(forms.ModelForm):		# forms.ModelForm 상속받음
    # 필드 추가 (직접 필드를 정의해도 됨)
    
    def __init__(self, *args, **kwargs):
        #생략
    
    class Meta:
        model = Notice			# 모델 연결
        fields = (			# 속성나열
            'name', 'title', 'content',
        )
        widgets = {			# default값 변경시
            'title' : forms.TextInput(attrs={'class': 'form-control'}),
            'content' : forms.Textarea(attrs={'class': 'form-control', 'rows': 10}),
        }
        label = {
            'name' : '이름',
            'title' : '제목',
            'content' : '내용',  
        }
      
    def save(self, commit=True):		# save() 오버라이딩
        instance = super().save(commit=False)
        #수정예정
        
        return instance
    
    def clean(self):						# clean() 오버라이딩
        cleaned_data = super().clean()
        title = cleaned_data.get('title')
        
        if '[공지]' in title:				# ValidationError 커스터마이징
            raise ValidationError('해당 문구는 사용할수 없습니다.')
        
        return cleaned_data
        
    
    
    # 위의 clean()을 아래와 같이 사용할 수도 있음
    def clean_title(self):
        title = self.cleaned_data.get('title')
        
        if '[공지]' in title:				# ValidationError 커스터마이징
             raise ValidationError('해당 문구는 사용할수 없습니다.')
    
        return title
        
        

→ 폼을 구현하기 위해서는 forms.ModelForm을 상속 받아야 함

→ ModelForm은 내부클래스인 Meta가 반드시 필요 함

 

○ class Meta

  - Meta 클래스 안에 model과 fields를 지정하면 모델폼이 자동으로 폼필드를 생성 함

  (model : 모델클래스 연결, fields : 폼에 사용할 속성 나열, label : 변수명 대신 출력시킬 값)

 

○ forms.ModelForm 메서드

 - save() :

 - clean() : 유효성검사 후 데이터를 받음

 - clean_필드명 : 해당 필드만 유효성검사

 

 

2. Form

# forms.py

class NoticeForm(forms.Form):		# forms.Form 상속받음
    name = forms.CharField(max_length=12, required=False, label='이름')
    title = forms.CharField(label='제목')
    content = forms.CharField(widget=forms.Textarea, lable='내용')      
    
    def __init__(self, *args, **kwargs):
      self.user = kwargs.pop('user')			### view로 부터 user 넘겨받기
      super().__init__(*args, **kwargs)
      self.fields['name'].widget.attrs.update({'class': 'form-control', 'value' : self.user.first_name})
      self.fields['title'].widget.attrs.update({'class': 'form-control'})
      
      
    def clean(self):
       #생략

→ 모델폼과는 다르게 필드를 직접 정의함

 

○ Form 필드 파라미터 (Model 필드 파라미터와 유사)

 - max_length : 최대글자수

 - required : 필수값

 - label : name, title, content와 같은 영어의 변수명 대신에 출력시킬 값

 - initial : 폼에서 입력시킬 초기값

 - validators : 유효성검사 (유효성 검사는 Model에서 하는걸 추천)

 

○ def __init__(self, *args, **kwargs) : 생성자

 - widget.attrs.update() : 위젯 속성값 변경

 

○ forms.Form 메서드

 - clean() : 유효성검사

 

★ View -> Form 데이터 넘기기

 - Form의 생성자의 파라미터로 데이터를 넘기면 됨

View

form = NoticeForm(user = request.user)				# GET방식
form = NoticeForm(request.POST, user = request.user) 	# POST방식

Form

class NoticeForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')		# pop을 이용하여 받음	
        super().__init__(*args, **kwargs)

● View

# views.py
from .forms import NoticeForm
from django.shortcuts import redirect

    def notice_create(request):
        if : request.method == "POST":		# POST방식
            form = NoticeForm(request.POST, user = request.user)
            if form.is_valid():
                notice = form.save(commit=False)	# 바로 저장하지 않고 꺼내와서 수정함
                notice.date = timezone.now()
                notice.save()				# 저장
                return redirect('notice')
        else : 					# GET방식
            form = NoticeForm(user = request.user)			### Form으로 user 매개변수 넘기기
            context =  {'form': form}
            return render(request, 'polls/notice.html', context)

→ form 속성에 사용할 폼 명시

→ GET방식일 경우 폼 출력, POST방식일 경우 DB에 저장

→ save(commit=False)를 사용하여 바로 Notice 모델에 저장하지 않고 수정을 할 수 있음

→ 수정이 끝나면 save()를 사용하여 저장

 

○ form.is_valid()

 - 검증에 성공한 값들은 사전타입으로 제공 (form.cleaned_data)

 - 검증에 실패시 form.error 에 오류 정보를 저장 -> 템플릿에서 {{ object_list.errors }} 로 출력가능

 

○ form.cleaned_data

 - is_valid()를 통해 검증된 값

 - dict형태

 

 

○ 모델객체에 저장방법

  ① 디폴트 생성자 사용

if form.is_valid():
    notice = Notice()
    notice.title = form.cleaned_data['title']
    notice.content = form.cleaned_data['content']
    notice.save()

  

  ② 생성자 사용

if form.is_valid():
    notice = Notice(title = form.cleaned_data['title'],
    			content = form.cleaned_data['content'])
    notice.save()

 

  ③ create() 사용

if form.is_valid():
    notice = Notice.objects.create(title = form.cleaned_data['title'],
    					content = form.cleaned_data['content'])

 


● Template

<!-- notice_create.html -->

{% extends 'blog/base.html' %}

{% block content %}
    <h1>Create Notice</h1>
    <form method="POST" class="post-form">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="save btn btn-default">Save</button>
    </form>
{% endblock %}

→ {{ form.as_p }} : form의 속성에 맞게 자동으로 html 태그들을 생성시키고 각 항목을 p태그로 감싸서 폼을 만들어 줌

→ {{ form.as_ul }} : ul태그로 감쌈

→ {{ form.as_table }} : table태그로 감쌈

 

더보기

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

쿼리셋(queryset)  (0) 2020.12.15
사용자 정보 가져오기(user)  (0) 2020.12.14
MTV 패턴 - Template  (0) 2020.12.09
MTV 패턴 - View  (0) 2020.12.09
MTV 패턴 - Model  (0) 2020.12.09

+ Recent posts