일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- Git
- AWS
- utils
- SQL
- algorithm
- stateful
- Django
- TDD
- Query
- codecov
- greedy
- ws
- ORM
- Unit Testing
- postreSQL
- Python
- Q objects
- dictionary
- Stack
- stack&que
- Programmers
- permutations
- 백준
- HTTP 완벽 가이드
- stateless
- was
- pytest
- Gunicorn
- Bruteforce
- combinations
- Today
- Total
해피 코딩!
Django form 정리 본문
Django form에 대하여 작성 단계에 있는 블로그 글 입니다. 지속적으로 글이 변경되는 점 양해 부탁드립니다.
외부의 요청을 Django server
는 view
를 통해 실행하여 응답합니다.
이 때 View
는 CBV
또는 FBV
로 구현을 할 수 있습니다.
Form 의 구성
forms.Form
forms.ModelForm
Form 을 HTML을 통해 표현하는 방법
반복문을 활용한 방법
context를 통해 form 을 html에 보낸 후 작성자는 반복문을 통해 form을 표현할 시 이런 방법을 사용합니다.
<form>
{% csrf_token %}
{% for filed in form %}
<p>{{ field.label }}</p>
{{ field }}
{% endfor %}
<button type="submit" class="btn btn-primary btn-box">btn</button>
</form>
load bootstrap3
html에서 부트스트랩을 로드하여 한 줄로 form의 필드들을 표현 합니다.
<form>
{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="btn btn-primary btn-box">btn</button>
</form>
각 필드 명 별로 호출
작성자는 보다 상세한 html을 작성할 때 사용하였습니다.
<form>
{% csrf_token %}
<table class="table">
<tr>
<th>접수 번호</th>
<td>{{ form.id }}</td>
<th></th>
<td></td>
</tr>
<tr>
<th><span>*</span> 업 체</th>
<td>{{ form.company }}</td>
<th>프로젝트명</th>
<td>{{ form.name }}</td>
</tr>
</form>
form clean_fieldname()을 활용한 에러 표현
Django 내부의 form.is_valid()
가 호출이 될 때의 순서는
- 폼이 데이터를 받으면
form.is_valid()
는form.full_clean()
를 호출합니다. form.full_clean()
은 폼 필드들과 각각의 필드 유효성을 하나하나 검사합니다.- 필드에 들어온 데이터에 대해
to_python()
이용하여 문제가 있을 시 validationError 에러를 일으킨다. - 폼에
clean_<field_name>()
메서드가 있을 시 해당 메서드를 실해앟ㄴ다.
각 Form Class는 필드를 가지고 있으며 이는clean()
, clean_filename()
함수를 사용할 수 있게 합니다.
이 때 각 필드별로 clean 메서드가 동작한 후, 전체 form에 대한 유효성이 통과하면서 form의 유효성 검사는 마무리가 됩니다.
clean_field
에 추가적으로 유효성을 검사하고 싶은 경우가 있을 것 입니다.
본인은 해당 두 가지 방법을 통해 에러를 반환하였습니다.
Two Scoops of Django
서적에서는
self.add_error('field_name', msg)
를 추천합니다.
개인적으로 추천하는 방법은 B
방법입니다. 출처가 정확히 기억나지 않으나 raise를 활용하는 것은 좋은 수단이라 기억하기 때문이며 추후, 출처에 대한 내용을 추가하도록 하겠습니다.
def clean_file(self):
if <추가할 유효성>:
# A. self.add_error('file', '데이터 분석에 필요한 필드가 없습니다.')
# return
# B. raise forms.ValidationError("데이터 분석에 필요한 필드가 없습니다.")
return self.cleaned_data['file']
이후 View 코드에서 유효성이 통과가 된다면 HTML 코드를 통해 에러를 표현하면 됩니다.
작성자는 이러한 방법으로 에러를 웹 페이지에 표현하였습니다.
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
{% for field in form %}
<p>{{ field.label }}</p>
{% if field.errors %}
<span style="color: red">{{ field.errors }}</span>
{% endif %}
{{ field }}
{% endfor %}
</div>
<button class="btn btn-primary">btn</button>
</form>
CBV(Class Base View)
- CBV 링크 → CBV을 사용하는 이유로는 표준이기 때문이며
- 이에 대한 단점으로는 추상화가 심하여 커스텀이 어렵다는 것이고
- 장점으로는 높은 생산성을 보장한다는 것이다.
urls
에서 호출 시view.as_view()
를 작성해야 한다.CBV
는 상속이 가능하다는 장점으로 많이 사용된다.- HTTP Method에 따라 처리가 가능하다.
FBV(Fucntional Base view)
- 쉬운 기능 생산이 가능하다.
- 가독성이 좋다.
form의 구조
widgets
을 통해서 폼의 형식과 class명이 포함 된attribute
를 추가한다.label
을 통해서 각 폼 필드의label
을 지정할 수 있다.__init__
메소드를 통해서 부모모델 User의 기본 설정을 (maxlength 등) 변경할 수 있다.
from django import forms
from django.contrib.auth import get_user_model
User = get_user_model()
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'email', 'password']
widgets = {
'username': forms.TextInput(attrs={'class': 'form-control', 'placeholder':'15자 이내로 입력 가능합니다.'}),
'email': forms.EmailInput(attrs={'class': 'form-control'}),
'password' : forms.PasswordInput(attrs={'class': 'form-control'}),
}
labels = {
'username': '닉네임',
'email': '이메일',
'password': '패스워드'
}
# 글자수 제한
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__( *args, **kwargs)
self.fields['username'].widget.attrs['maxlength'] = 15
form 호출
# urls의 app_name은 view name의 중복을 피할 수 있다.
def user_create(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
form.save()
return redirect('user-list')
form = UserForm
context = {
'form': form
}
return render(request, 'system/user/add_account.html', context=context)
참고 자료
'Django' 카테고리의 다른 글
Django 유틸리티 (0) | 2021.03.11 |
---|---|
Django의 쿼리와 데이터베이스 레이어 (4) | 2020.12.18 |
Django를 사용하게 된 이유 (0) | 2020.12.15 |
pytest를 사용하는 이유 (0) | 2020.11.23 |
Django 구성에 대한 이해 (0) | 2020.11.23 |