Search
Duplicate

Forms

Django Form

1. ํผ(Form)์ด๋ž€?

์‚ฌ์šฉ์ž ์ž…๋ ฅ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ๊ฒ€์ฆํ•˜๋Š” ๋„๊ตฌ
โ€ข
Django์˜ forms ๋ชจ๋“ˆ์„ ์‚ฌ์šฉ
โ€ข
HTML <form> ํƒœ๊ทธ๋ฅผ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์คŒ

Django Form์˜ ์ฃผ์š” ๊ธฐ๋Šฅ

๋‹ค์Œ์€ Django Form์˜ ์ฃผ์š” ๊ธฐ๋Šฅ์„ ํ‘œ๋กœ ์ •๋ฆฌํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค:
๊ธฐ๋Šฅ
์„ค๋ช…
๋ฐ์ดํ„ฐ ๊ฒ€์ฆ
์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ์„ฑ์„ ์ž๋™์œผ๋กœ ๊ฒ€์‚ฌ
HTML ์ƒ์„ฑ
ํผ ํ•„๋“œ์— ๋Œ€ํ•œ HTML ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ƒ์„ฑ
๋ฐ์ดํ„ฐ ๋ณ€ํ™˜
POST ๋ฐ์ดํ„ฐ๋ฅผ ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜
๋ณด์•ˆ ๊ธฐ๋Šฅ
CSRF ๋ณดํ˜ธ์™€ ๊ฐ™์€ ๋ณด์•ˆ ๊ธฐ๋Šฅ ์ œ๊ณต
์—๋Ÿฌ ์ฒ˜๋ฆฌ
ํผ ๊ฒ€์ฆ ์‹คํŒจ ์‹œ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๊ด€๋ฆฌ
์ดˆ๊ธฐ๊ฐ’ ์„ค์ •
ํผ ํ•„๋“œ์˜ ์ดˆ๊ธฐ๊ฐ’์„ ์‰ฝ๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ

2. ํผ์˜ ์ข…๋ฅ˜

์ข…๋ฅ˜
์„ค๋ช…
ํด๋ž˜์Šค
์ผ๋ฐ˜ ํผ
์‚ฌ์šฉ์ž ์ •์˜ ์ž…๋ ฅ ํ•„๋“œ
forms.Form
๋ชจ๋ธ ํผ
๋ชจ๋ธ ๊ธฐ๋ฐ˜ ์ž๋™ ์ƒ์„ฑ
forms.ModelForm

3. ์ผ๋ฐ˜ Form ์˜ˆ์ œ

# forms.py from django import forms class ContactForm(forms.Form): name = forms.CharField(max_length=100) email = forms.EmailField() message = forms.CharField(widget=forms.Textarea)
Python
๋ณต์‚ฌ
# views.py from .forms import ContactForm def contact_view(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): # ์ฒ˜๋ฆฌ ๋กœ์ง return redirect('success') else: form = ContactForm() return render(request, 'contact.html', {'form': form})
Python
๋ณต์‚ฌ

4. ModelForm ์˜ˆ์ œ

# models.py class Post(models.Model): title = models.CharField(max_length=200) content = models.TextField()
Python
๋ณต์‚ฌ
# forms.py from .models import Post from django import forms class PostForm(forms.ModelForm): class Meta: model = Post fields = ['title', 'content']
Python
๋ณต์‚ฌ
# views.py def create_post(request): if request.method == 'POST': form = PostForm(request.POST) if form.is_valid(): form.save() return redirect('post_list') else: form = PostForm() return render(request, 'post_form.html', {'form': form})
Python
๋ณต์‚ฌ

5. ํ…œํ”Œ๋ฆฟ์—์„œ ํผ ๋ Œ๋”๋ง

<!-- post_form.html --> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">๋“ฑ๋ก</button> </form>
HTML
๋ณต์‚ฌ

ํผ ๋ Œ๋”๋ง ๋ฐฉ์‹

๋ฉ”์†Œ๋“œ
์„ค๋ช…
์ถœ๋ ฅ ํ˜•ํƒœ
as_p()
๊ฐ ํ•„๋“œ๋ฅผ <p> ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์„œ ์ถœ๋ ฅ
๋‹จ๋ฝ ํ˜•ํƒœ๋กœ ๊ตฌ๋ถ„๋˜์–ด ํ‘œ์‹œ
as_table()
๊ฐ ํ•„๋“œ๋ฅผ <tr> ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์„œ ์ถœ๋ ฅ
ํ…Œ์ด๋ธ” ํ–‰ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ
as_ul()
๊ฐ ํ•„๋“œ๋ฅผ <li> ํƒœ๊ทธ๋กœ ๊ฐ์‹ธ์„œ ์ถœ๋ ฅ
๋ชฉ๋ก ์•„์ดํ…œ ํ˜•ํƒœ๋กœ ํ‘œ์‹œ
Tip: ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ์‹์€ as_p()์ž…๋‹ˆ๋‹ค.

6. ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ & ์ปค์Šคํ…€ ์œ ํšจ์„ฑ

๊ธฐ๋ณธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

Django Form์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•„๋“œ ํƒ€์ž…์— ๋”ฐ๋ฅธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
# forms.py from django import forms from django.core.validators import RegexValidator class UserForm(forms.Form): username = forms.CharField( validators=[ RegexValidator( regex='^[a-zA-Z]{6,}$', message='์•„์ด๋””๋Š” ์˜๋ฌธ 6์ž๋ฆฌ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', code='invalid_username' ) ] ) password = forms.CharField( widget=forms.PasswordInput, validators=[ RegexValidator( regex='^(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,}$', message='๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” 8์ž๋ฆฌ ์ด์ƒ์ด๋ฉฐ, ํŠน์ˆ˜๋ฌธ์ž๋ฅผ 1๊ฐœ ์ด์ƒ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', code='invalid_password' ) ] )
Python
๋ณต์‚ฌ

์ปค์Šคํ…€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

clean_ ๋ฉ”์†Œ๋“œ๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ •์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
from django import forms from django.contrib.auth.models import User from django.core.exceptions import ValidationError import re class UserForm(forms.Form): username = forms.CharField() password = forms.CharField(widget=forms.PasswordInput) def clean_username(self): username = self.cleaned_data['username'] if not re.match(r'^[a-zA-Z]{6,}$', username): raise ValidationError('์•„์ด๋””๋Š” ์˜๋ฌธ 6์ž๋ฆฌ ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', code='invalid_username') if User.objects.filter(username=username).exists(): raise ValidationError('์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์•„์ด๋””์ž…๋‹ˆ๋‹ค.') return username def clean_password(self): password = self.cleaned_data['password'] if not re.match(r'^(?=.*[!@#$%^&*])[A-Za-z\d!@#$%^&*]{8,}$', password): raise ValidationError('๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” 8์ž๋ฆฌ ์ด์ƒ์ด๋ฉฐ, ํŠน์ˆ˜๋ฌธ์ž๋ฅผ 1๊ฐœ ์ด์ƒ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.', code='invalid_password') return password
Python
๋ณต์‚ฌ
Tip: clean_() ๋ฉ”์†Œ๋“œ๋Š” ํ•ด๋‹น ํ•„๋“œ์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ฒฐ๊ณผ๋Š” form.errors๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

7. ์‹ค์Šต ๊ณผ์ œ ์˜ˆ์‹œ

์‹ค์Šต ์ฃผ์ œ
์„ค๋ช…
์—ฐ๋ฝ์ฒ˜ ํผ ๋งŒ๋“ค๊ธฐ
์ด๋ฆ„, ์ด๋ฉ”์ผ, ๋ฉ”์‹œ์ง€ ์ž…๋ ฅ ํ›„ DB ์ €์žฅ ๋˜๋Š” ์ฝ˜์†” ์ถœ๋ ฅ
๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ํผ
Post ๋ชจ๋ธ ๊ธฐ๋ฐ˜์˜ ModelForm ๋งŒ๋“ค๊ธฐ
๋กœ๊ทธ์ธ ํผ
์‚ฌ์šฉ์ž ์ž…๋ ฅ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํฌํ•จ

๋ณด๋„ˆ์Šค: ์œ„์ ฏ & ์Šคํƒ€์ผ ์ ์šฉ

class StyledForm(forms.Form): name = forms.CharField(widget=forms.TextInput(attrs={'class': 'form-control'}))
Python
๋ณต์‚ฌ
Bootstrap๊ณผ ํ•จ๊ป˜ ์“ฐ๋ฉด ํ›Œ๋ฅญํ•œ ๋””์ž์ธ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

์š”์•ฝ

๊ธฐ๋Šฅ
์„ค๋ช…
forms.Form
์ผ๋ฐ˜ ํผ ํด๋ž˜์Šค, ์ˆ˜๋™์œผ๋กœ ํ•„๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉ
forms.ModelForm
๋ชจ๋ธ๊ณผ ์—ฐ๋™๋œ ํผ ํด๋ž˜์Šค, ๋ชจ๋ธ ํ•„๋“œ ๊ธฐ๋ฐ˜ ์ž๋™ ์ƒ์„ฑ
form.is_valid()
ํผ ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ˆ˜ํ–‰
form.cleaned_data
์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ›„ ์ •์ œ๋œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผ
form.save()
ModelForm์—์„œ ๊ฒ€์ฆ๋œ ๋ฐ์ดํ„ฐ๋ฅผ DB์— ์ €์žฅ

Django ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์˜ˆ์ œ

1. ๊ธฐ๋ณธ ๊ฐœ์š”

โ€ข
Django์˜ ๊ธฐ๋ณธ User ๋ชจ๋ธ (django.contrib.auth.models.User) ์‚ฌ์šฉ
โ€ข
forms.ModelForm์œผ๋กœ ํšŒ์›๊ฐ€์ž… ํผ ์ƒ์„ฑ
โ€ข
๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ํ•ด์‹œ์ฒ˜๋ฆฌ ๋˜์–ด ์ €์žฅ๋จ (set_password() ์‚ฌ์šฉ)

2. ํผ ๋งŒ๋“ค๊ธฐ (forms.py)

# accounts/forms.py from django import forms from django.contrib.auth.models import User from django.contrib.auth.forms import UserCreationForm class SignupForm(UserCreationForm): # UserCreationForm์€ ๊ธฐ๋ณธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํฌํ•จ email = forms.EmailField(required=True) class Meta: model = User fields = ('username', 'email', 'password1', 'password2')
Python
๋ณต์‚ฌ
password1, password2: ์ž๋™ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ ์ฒ˜๋ฆฌ ํฌํ•จ
UserCreationForm์„ ์ƒ์†ํ•˜๋ฉด ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•ด์‹ฑ๊ณผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ์ž๋™ ์ฒ˜๋ฆฌ๋จ

3. ๋ทฐ ํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ (views.py)

# accounts/views.py from django.shortcuts import render, redirect from .forms import SignupForm from django.contrib import messages def signup_view(request): if request.method == 'POST': form = SignupForm(request.POST) if form.is_valid(): form.save() messages.success(request, 'ํšŒ์›๊ฐ€์ž…์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!') return redirect('login') # ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ else: form = SignupForm() return render(request, 'accounts/signup.html', {'form': form})
Python
๋ณต์‚ฌ

4. URL ์„ค์ • (urls.py)

# accounts/urls.py from django.urls import path from .views import signup_view urlpatterns = [ path('signup/', signup_view, name='signup'), ]
Python
๋ณต์‚ฌ
# ํ”„๋กœ์ ํŠธ urls.py์— ์•ฑ URL ์—ฐ๊ฒฐ # mysite/urls.py from django.urls import path, include urlpatterns = [ path('accounts/', include('accounts.urls')), # http://localhost:8000/accounts/signup/ ]
Python
๋ณต์‚ฌ

5. ํ…œํ”Œ๋ฆฟ ์ž‘์„ฑ (signup.html)

<!-- templates/accounts/signup.html --> <h2>ํšŒ์›๊ฐ€์ž…</h2> <form method="post"> {% csrf_token %} {{ form.as_p }} <button type="submit">๊ฐ€์ž…ํ•˜๊ธฐ</button> </form>
HTML
๋ณต์‚ฌ

6. ์ž‘๋™ ํ๋ฆ„ ์š”์•ฝ

1.
์‚ฌ์šฉ์ž๊ฐ€ /accounts/signup/ ํŽ˜์ด์ง€๋กœ ์ด๋™
2.
๊ฐ€์ž… ํผ์— ์ž…๋ ฅ ํ›„ ์ œ์ถœ
3.
Django๊ฐ€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ํ›„ User ๊ฐ์ฒด ์ƒ์„ฑ (form.save())
4.
์„ฑ๊ณต ์‹œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋””๋ ‰์…˜

ํ™•์žฅ ํŒ

๊ธฐ๋Šฅ
๋ฐฉ๋ฒ•
๋กœ๊ทธ์ธ ํ›„ ์ž๋™ ๋กœ๊ทธ์ธ
login(request, user) ์‚ฌ์šฉ
์ค‘๋ณต ์ด๋ฉ”์ผ ๊ฒ€์ฆ
clean_email() ๋ฉ”์„œ๋“œ ์˜ค๋ฒ„๋ผ์ด๋“œ
์ถ”๊ฐ€ ํ•„๋“œ (์˜ˆ: ์ƒ๋…„์›”์ผ)
Custom User ๋ชจ๋ธ ์‚ฌ์šฉ ๋˜๋Š” UserProfile ์—ฐ๊ฒฐ

์‹ค์Šต ์•„์ด๋””์–ด

โ€ข
์ด๋ฉ”์ผ ์ค‘๋ณต ์ฒดํฌ ์ถ”๊ฐ€
โ€ข
๊ฐ€์ž… ํ›„ ํ™˜์˜ ์ด๋ฉ”์ผ ๋ฐœ์†ก
โ€ข
๊ฐ€์ž… ์„ฑ๊ณต ์‹œ ์ž๋™ ๋กœ๊ทธ์ธ
โ€ข
๊ฐ€์ž… ์‹œ ์•ฝ๊ด€ ๋™์˜ ์ฒดํฌ๋ฐ•์Šค ์ถ”๊ฐ€