κ°λ ₯νκ³ ν¨μ¨μ μΈ μΉ κ°λ°μ μν΄ Djangoμ ν΄λμ€ κΈ°λ° μ λ€λ¦ λ·°λ₯Ό 컀μ€ν°λ§μ΄μ§νλ λ°©λ²μ λν μ’ ν© κ°μ΄λμ λλ€. νΉμ μꡬ μ¬νμ λ§κ² λ·°λ₯Ό μ‘°μ νλ λ°©λ²μ λ°°μ°μΈμ.
Django ν΄λμ€ κΈ°λ° λ·°: μ λ€λ¦ λ·° 컀μ€ν°λ§μ΄μ§ λ§μ€ν°νκΈ°
Djangoμ ν΄λμ€ κΈ°λ° λ·°(CBV)λ μΉ μ ν리μΌμ΄μ μ ꡬμΆνλ κ°λ ₯νκ³ μ¬μ¬μ© κ°λ₯ν λ°©λ²μ μ 곡ν©λλ€. μ λ€λ¦ λ·°λ CBVμ νμ μ§ν©μΌλ‘ λͺ©λ‘ νμ, μμΈ λ·°, κ°μ²΄ μμ±, μ λ°μ΄νΈ λ° μμ μ κ°μ μΌλ°μ μΈ μμ μ λν 미리 λΉλλ μ루μ μ μ 곡ν©λλ€. μ΄λ¬ν μ λ€λ¦ λ·°λ λ§€μ° νΈλ¦¬νμ§λ§ μ ν리μΌμ΄μ μ νΉμ μꡬ μ¬νμ μλ²½νκ² λ§μΆλ €λ©΄ 컀μ€ν°λ§μ΄μ§μ΄ νμν κ²½μ°κ° λ§μ΅λλ€. μ΄ μ’ ν© κ°μ΄λλ Djangoμ μ λ€λ¦ λ·°λ₯Ό 컀μ€ν°λ§μ΄μ§νλ λ€μν κΈ°μ μ μ΄ν΄λ³΄κ³ ν¨μ¨μ μ΄κ³ μ μ§ κ΄λ¦¬ κ°λ₯ν μΉ μ ν리μΌμ΄μ μ ꡬμΆν μ μλλ‘ μ§μν©λλ€.
Djangoμ ν΄λμ€ κΈ°λ° λ·° μ΄ν΄
컀μ€ν°λ§μ΄μ§μ μμνκΈ° μ μ CBV λ° μ λ€λ¦ λ·°μ κΈ°λ³Έ μ¬νμ λ€μ μ΄ν΄ λ³΄κ² μ΅λλ€. κΈ°μ‘΄μ ν¨μ κΈ°λ° λ·°(FBV)λ λ¨μΌ ν¨μ λ΄μμ HTTP μμ²μ μ§μ μ²λ¦¬ν©λλ€. λ°λ©΄μ CBVλ λ·° λ‘μ§μ ν΄λμ€λ‘ ꡬμ±νμ¬ λ³΄λ€ κ΅¬μ‘°νλκ³ κ°μ²΄ μ§ν₯μ μΈ μ κ·Ό λ°©μμ μ 곡ν©λλ€. μ΄λ₯Ό ν΅ν΄ μ½λ ꡬμ±, μ¬μ¬μ©μ± λ° ν μ€νΈ κ°λ₯μ±μ΄ ν₯μλ©λλ€.
μ λ€λ¦ λ·°λ μΌλ°μ μΈ μΉ κ°λ° μμ
μ μ²λ¦¬νλλ‘ μ€κ³λ 미리 λΉλλ CBVμ
λλ€. View
λ° TemplateView
μ κ°μ κΈ°λ³Έ ν΄λμ€μμ μμνκ³ μ λ¬Ένλ κΈ°λ₯μ μ 곡ν©λλ€. μΌλ°μ μΈ μ λ€λ¦ λ·°λ λ€μκ³Ό κ°μ΅λλ€.
ListView
: κ°μ²΄ λͺ©λ‘μ νμν©λλ€.DetailView
: λ¨μΌ κ°μ²΄μ μΈλΆ μ 보λ₯Ό νμν©λλ€.CreateView
: νΌμ μ¬μ©νμ¬ κ°μ²΄ μμ±μ μ²λ¦¬ν©λλ€.UpdateView
: νΌμ μ¬μ©νμ¬ κ°μ²΄ μ λ°μ΄νΈλ₯Ό μ²λ¦¬ν©λλ€.DeleteView
: κ°μ²΄ μμ λ₯Ό μ²λ¦¬ν©λλ€.
μ΄λ¬ν μ λ€λ¦ λ·°λ κ²¬κ³ ν ν λλ₯Ό μ 곡νμ§λ§ μ€μ μ ν리μΌμ΄μ μμλ μ’ μ’ ν΄λΉ λμμ μ‘°μ ν΄μΌ ν©λλ€. λ€μν 컀μ€ν°λ§μ΄μ§ κΈ°μ μ μ΄ν΄λ³΄κ² μ΅λλ€.
컀μ€ν°λ§μ΄μ§ κΈ°μ
Djangoμ μ λ€λ¦ λ·°λ₯Ό 컀μ€ν°λ§μ΄μ§νλ λ°©λ²μλ κ°λ¨ν μμ± μ¬μ μλΆν° λ 볡μ‘ν λ©μλ μ¬μ μκΉμ§ μ¬λ¬ κ°μ§κ° μμ΅λλ€. μ μ ν κΈ°μ μ νμν 컀μ€ν°λ§μ΄μ§ μμ€μ λ°λΌ λ€λ¦ λλ€.
1. μμ± μ¬μ μ
κ°μ₯ κ°λ¨ν ννμ 컀μ€ν°λ§μ΄μ§μ μ λ€λ¦ λ·° ν΄λμ€μ μμ±μ μ¬μ μνλ κ²μ λλ€. μ΄λ λͺ¨λΈ, ν νλ¦Ώ μ΄λ¦ λλ 컨ν μ€νΈ κ°μ²΄ μ΄λ¦κ³Ό κ°μ κΈ°λ³Έ μμ±μ μμ νλ λ° μ΄μμ μ λλ€.
μ: ListView
컀μ€ν°λ§μ΄μ§
κΈ°μ¬ λͺ©λ‘μ νμνκ³ μΆμ§λ§ μ¬μ©μ μ§μ ν νλ¦Ώκ³Ό λ€λ₯Έ 컨ν μ€νΈ κ°μ²΄ μ΄λ¦μ μ¬μ©νλ €λ κ²½μ°λ₯Ό κ°μ ν΄ λ³΄κ² μ΅λλ€.
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = 'articles/article_list.html'
context_object_name = 'articles'
def get_queryset(self):
return Article.objects.filter(is_published=True).order_by('-publication_date')
μ΄ μμμλ model
, template_name
λ° context_object_name
μμ±μ μ¬μ μνμ΅λλ€. λν κΈ°μ¬λ₯Ό νν°λ§νκ³ κ²μ λ μ§λ³λ‘ μ λ ¬νκΈ° μν΄ get_queryset
λ©μλλ₯Ό μ¬μ μνμ΅λλ€. get_queryset
λ©μλλ₯Ό μ¬μ©νλ©΄ λͺ©λ‘ λ·°μ ν¬ν¨ν κ°μ²΄λ₯Ό μ μ΄ν μ μμ΅λλ€. μ΄λ νν°λ§, μ λ ¬ λ° νμ΄μ§ λ§€κΉμ ꡬννλ λ° μ μ©ν©λλ€.
2. λ©μλ μ¬μ μ
λ©μλ μ¬μ μλ₯Ό μ¬μ©νλ©΄ μ λ€λ¦ λ·° ν΄λμ€μμ κΈ°μ‘΄ λ©μλμ λμμ μμ ν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ λ·°μ λ‘μ§μ λ ν¨κ³Όμ μΌλ‘ μ μ΄ν μ μμ΅λλ€. μ¬μ μν μΌλ°μ μΈ λ©μλλ λ€μκ³Ό κ°μ΅λλ€.
get_queryset()
: λ·°μμ μ¬μ©νλ 쿼리μ μ μ μ΄ν©λλ€.get_context_data()
: ν νλ¦Ώ 컨ν μ€νΈμ λ°μ΄ν°λ₯Ό μΆκ°ν©λλ€.form_valid()
: νΌ μ μΆμ΄ μ±κ³΅μ μΌλ‘ μλ£λλ©΄ μ²λ¦¬ν©λλ€.form_invalid()
: νΌ μ μΆμ΄ μ ν¨νμ§ μμ κ²½μ° μ²λ¦¬ν©λλ€.get_success_url()
: νΌ μ μΆμ΄ μ±κ³΅μ μΌλ‘ μλ£λ ν 리λλ μ ν URLμ κ²°μ ν©λλ€.get_object()
: DetailView, UpdateView λ° DeleteViewμ λν κ°μ²΄λ₯Ό κ²μν©λλ€.
μ: DetailView
컀μ€ν°λ§μ΄μ§
κΈ°μ¬μ μΈλΆ μ 보λ₯Ό νμνκ³ μΆμ§λ§ κ΄λ ¨ μ£Όμλ ν νλ¦Ώ 컨ν μ€νΈμ ν¬ν¨νλ €λ κ²½μ°λ₯Ό κ°μ ν΄ λ³΄κ² μ΅λλ€.
from django.views.generic import DetailView
from .models import Article, Comment
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/article_detail.html'
context_object_name = 'article'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['comments'] = Comment.objects.filter(article=self.object, is_approved=True)
return context
μ¬κΈ°μλ get_context_data()
λ©μλλ₯Ό μ¬μ μνμ¬ comments
λ³μλ₯Ό ν
νλ¦Ώ 컨ν
μ€νΈμ μΆκ°νμ΅λλ€. μ΄λ κ² νλ©΄ article_detail.html
ν
νλ¦Ώμμ κ΄λ ¨ μ£Όμμ μ½κ² μ‘μΈμ€νκ³ νμν μ μμ΅λλ€.
3. λ―Ήμ€μΈ μ¬μ©
λ―Ήμ€μΈμ νΉμ κΈ°λ₯μ μ 곡νλ μ¬μ¬μ© κ°λ₯ν ν΄λμ€μ λλ€. μ λ€λ¦ λ·°μ κ²°ν©νμ¬ λ·°μ ν΅μ¬ λ‘μ§μ μμ νμ§ μκ³ λ κΈ°λ₯μ μΆκ°ν μ μμ΅λλ€. Djangoλ μ¬λ¬ κ°μ§ κΈ°λ³Έ μ 곡 λ―Ήμ€μΈμ μ 곡νλ©° μ§μ λ§λ€ μλ μμ΅λλ€.
μ: LoginRequiredMixin
μ¬μ©
LoginRequiredMixin
μ λ‘κ·ΈμΈν μ¬μ©μλ§ νΉμ λ·°μ μ‘μΈμ€ν μ μλλ‘ ν©λλ€.
from django.views.generic import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = '/articles/' # μνλ μ±κ³΅ URLλ‘ λ°κΏλλ€.
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
μ΄ μμμλ LoginRequiredMixin
μ μ¬μ©νμ¬ λ‘κ·ΈμΈν μ¬μ©μλ§ ArticleCreateView
μ μ‘μΈμ€ν μ μλλ‘ μ ννμ΅λλ€. λν form_valid
λ©μλλ₯Ό μ¬μ μνμ¬ κΈ°μ¬μ μμ±μλ₯Ό νμ¬ μ¬μ©μλ‘ μλ μ€μ νμ΅λλ€. μ΄λ λ―Ήμ€μΈμ λ©μλ μ¬μ μμ κ²°ν©νμ¬ λ³΅μ‘ν 컀μ€ν°λ§μ΄μ§μ λ¬μ±νλ λ°©λ²μ 보μ¬μ€λλ€.
μ¬μ©μ μ§μ λ―Ήμ€μΈ λ§λ€κΈ°
μ체 λ―Ήμ€μΈμ λ§λ€μ΄ μ¬μ¬μ© κ°λ₯ν λ‘μ§μ μΊ‘μνν μλ μμ΅λλ€. μλ₯Ό λ€μ΄ νμ¬ μ¬μ©μλ₯Ό λͺ¨λΈ μΈμ€ν΄μ€μ μμ±μλ‘ μλ μ€μ νλ λ―Ήμ€μΈ λλ κΆν κ²μ¬λ₯Ό μ²λ¦¬νλ λ―Ήμ€μΈμ λ§λ€ μ μμ΅λλ€.
from django.contrib.auth.mixins import UserPassesTestMixin
class AuthorRequiredMixin(UserPassesTestMixin):
def test_func(self):
return self.request.user.is_staff or (self.request.user == self.get_object().author)
def handle_no_permission(self):
# μνλ 리λλ μ
λλ μ€λ₯ μ²λ¦¬λ‘ λ°κΏλλ€.
return redirect('permission_denied') # λλ μμΈλ₯Ό λ°μμν΅λλ€.
μ΄ AuthorRequiredMixin
μ μ§μ λλ κ°μ²΄μ μμ±μλ§ μ‘μΈμ€ν μ μλλ‘ ν©λλ€. μ΄ λ―Ήμ€μΈμ UpdateView
λλ DeleteView
μ ν¨κ» μ¬μ©νμ¬ κΆν μλ μ¬μ©μλ§ κ°μ²΄λ₯Ό μμ νκ±°λ μμ ν μ μλλ‘ ν μ μμ΅λλ€.
4. ν νλ¦Ώ 컀μ€ν°λ§μ΄μ§
μμ κΈ°μ μ λ·°μ λ‘μ§μ μμ νλ λ° μ€μ μ λλ λ°λ©΄ ν νλ¦Ώ 컀μ€ν°λ§μ΄μ§μ λ°μ΄ν° νμλ₯Ό μ μ΄νλ λ° μ€μν©λλ€. μ λ€λ¦ λ·°λ ν νλ¦Ώμ μ¬μ©νμ¬ HTML μΆλ ₯μ λ λλ§ν©λλ€. μ΄λ¬ν ν νλ¦Ώμ 컀μ€ν°λ§μ΄μ§νμ¬ μ ν리μΌμ΄μ μ λμμΈ λ° λΈλλ©κ³Ό μΌμΉμν¬ μ μμ΅λλ€.
ν νλ¦Ώ λͺ λͺ κ·μΉ
μ λ€λ¦ λ·°λ νΉμ ν νλ¦Ώ λͺ λͺ κ·μΉμ λ°λ¦ λλ€. μλ₯Ό λ€λ©΄ λ€μκ³Ό κ°μ΅λλ€.
ListView
:<app_name>/<model_name>_list.html
(μ:articles/article_list.html
)DetailView
:<app_name>/<model_name>_detail.html
(μ:articles/article_detail.html
)CreateView
/UpdateView
:<app_name>/<model_name>_form.html
(μ:articles/article_form.html
)DeleteView
:<app_name>/<model_name>_confirm_delete.html
(μ:articles/article_confirm_delete.html
)
λ·° ν΄λμ€μμ template_name
μμ±μ μ¬μ μνμ¬ λ€λ₯Έ ν
νλ¦Ώμ μ¬μ©ν μ μμ΅λλ€. ν
νλ¦Ώ λ΄μμ 컨ν
μ€νΈ κ°μ²΄λ₯Ό ν΅ν΄ λ·°μμ μ 곡νλ λ°μ΄ν°μ μ‘μΈμ€ν μ μμ΅λλ€. κΈ°λ³Έ 컨ν
μ€νΈ κ°μ²΄ μ΄λ¦μ μΌλ°μ μΌλ‘ λͺ¨λΈ μ΄λ¦μ μλ¬Έμ λ²μ μ
λλ€(μ: Article
μ κ²½μ° article
). context_object_name
μμ±μ μ¬μ©νμ¬ μ΄λ₯Ό λ³κ²½ν μ μμ΅λλ€.
μ: ListView
ν
νλ¦Ώ 컀μ€ν°λ§μ΄μ§
articles/article_list.html
ν
νλ¦Ώμμ articles
컨ν
μ€νΈ λ³μ(μμ ArticleListView
μμ μ μλ¨)λ₯Ό λ°λ³΅νμ¬ κΈ°μ¬ λͺ©λ‘μ νμν μ μμ΅λλ€.
<h1>κΈ°μ¬</h1>
<ul>
{% for article in articles %}
<li><a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a></li>
{% endfor %}
</ul>
5. νΌ μ»€μ€ν°λ§μ΄μ§(CreateView λ° UpdateView)
CreateView
λ° UpdateView
λ μ¬μ©μ μ
λ ₯μ μ²λ¦¬νκΈ° μν΄ Django νΌμ μμ‘΄ν©λλ€. μ΄λ¬ν νΌμ 컀μ€ν°λ§μ΄μ§νλ©΄ νμλλ νλ, μ ν¨μ± κ²μ¬ κ·μΉ λ° λͺ¨μμ μ μ΄ν μ μμ΅λλ€.
form_class
μ¬μ©
λ·° ν΄λμ€μμ form_class
μμ±μ μ¬μ©νμ¬ μ¬μ©ν νΌ ν΄λμ€λ₯Ό μ§μ ν μ μμ΅λλ€. νΌ ν΄λμ€λ₯Ό μ§μ νμ§ μμΌλ©΄ Djangoλ λ·°μ μ°κ²°λ λͺ¨λΈμ κΈ°λ°μΌλ‘ ModelForm
μ μλμΌλ‘ μμ±ν©λλ€.
νΌ λ©μλ μ¬μ μ
νΌ ν΄λμ€μμ λ©μλλ₯Ό μ¬μ μνμ¬ ν΄λΉ λμμ 컀μ€ν°λ§μ΄μ§ν μ μμ΅λλ€. μ¬μ μν μΌλ°μ μΈ λ©μλλ λ€μκ³Ό κ°μ΅λλ€.
__init__()
: νΌμ μ΄κΈ°ννκ³ ν΄λΉ νλλ₯Ό μμ ν©λλ€.clean()
: μ¬λ¬ νλμμ μ¬μ©μ μ§μ μ ν¨μ± κ²μ¬λ₯Ό μνν©λλ€.clean_<field_name>()
: νΉμ νλμ λν μ¬μ©μ μ§μ μ ν¨μ± κ²μ¬λ₯Ό μνν©λλ€.
μ: κΈ°μ¬ νΌ μ»€μ€ν°λ§μ΄μ§
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'is_published']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['content'].widget = forms.Textarea(attrs={'rows': 5})
def clean_title(self):
title = self.cleaned_data['title']
if len(title) < 5:
raise forms.ValidationError("μ λͺ©μ 5μ μ΄μμ΄μ΄μΌ ν©λλ€.")
return title
μ΄ μμμλ Meta
ν΄λμ€μμ fields
μμ±μ μ€μ νμ¬ νΌμ ν¬ν¨ν΄μΌ νλ νλλ₯Ό μ§μ νμ¬ ArticleForm
μ 컀μ€ν°λ§μ΄μ§νμ΅λλ€. λν __init__()
λ©μλλ₯Ό μ¬μ μνμ¬ content
νλμ μμ ―μ 컀μ€ν°λ§μ΄μ§νκ³ clean_title()
λ©μλλ₯Ό μ¬μ μνμ¬ title
νλμ λν μ¬μ©μ μ§μ μ ν¨μ± κ²μ¬λ₯Ό μΆκ°νμ΅λλ€.
6. λμ νΌ μ²λ¦¬
κ²½μ°μ λ°λΌ μ¬μ©μ λλ κΈ°ν μμΈμ λ°λΌ νΌμ λμ μΌλ‘ μ‘°μ ν΄μΌ ν μλ μμ΅λλ€. λ·° ν΄λμ€μμ get_form_kwargs()
λ©μλλ₯Ό μ¬μ μνμ¬ μ΄λ₯Ό λ¬μ±ν μ μμ΅λλ€. μ΄ λ©μλλ₯Ό μ¬μ©νλ©΄ νΌμ μμ±μμ μΆκ° ν€μλ μΈμλ₯Ό μ λ¬ν μ μμ΅λλ€.
μ: μ¬μ©μμκ² νΌ μ λ¬
from django.views.generic import CreateView
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(CreateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = '/articles/' # μνλ μ±κ³΅ URLλ‘ λ°κΏλλ€.
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
κ·Έλ° λ€μ ArticleForm
μμ __init__()
λ©μλμ user
ν€μλ μΈμλ₯Ό ν΅ν΄ μ¬μ©μμ μ‘μΈμ€ν μ μμ΅λλ€.
from django import forms
from .models import Article
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title', 'content', 'is_published']
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if self.user and not self.user.is_staff:
del self.fields['is_published'] # μ§μλ§ κ²μν μ μμ΅λλ€.
μ΄ μμμλ νμ¬ μ¬μ©μλ₯Ό νΌμ μ λ¬νκ³ μ¬μ©μκ° μ§μμ΄ μλ κ²½μ° is_published
νλλ₯Ό λμ μΌλ‘ μ κ±°ν©λλ€. μ΄λ μ¬μ©μμ κΆνμ λ°λΌ νΌμ λμ μΌλ‘ μ‘°μ ν μ μλ λ°©λ²μ 보μ¬μ€λλ€.
κ³ κΈ μ»€μ€ν°λ§μ΄μ§: λ·°μ μ¬μ©
νΉν APIμ κ΄λ ¨λ λ 볡μ‘ν μ ν리μΌμ΄μ μ κ²½μ° Django REST Framework(DRF)μ λ·°μ μ¬μ©μ κ³ λ €νμμμ€. λ·°μ μ κ΄λ ¨ λ·°(μ: λͺ©λ‘, μμ±, κ²μ, μ λ°μ΄νΈ, μμ )λ₯Ό λ¨μΌ ν΄λμ€λ‘ κ²°ν©νμ¬ API μλν¬μΈνΈλ₯Ό κ΄λ¦¬νλ λ κΉλνκ³ μ‘°μ§μ μΈ λ°©λ²μ μ 곡ν©λλ€.
μ: ArticleViewSet λ§λ€κΈ°
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
μ΄ κ°λ¨ν ArticleViewSet
μ κΈ°μ¬μ λν λͺ¨λ νμ€ CRUD(μμ±, μ½κΈ°, μ
λ°μ΄νΈ, μμ ) μμ
μ μ 곡ν©λλ€. get_queryset()
, perform_create()
λ° perform_update()
μ κ°μ λ©μλλ₯Ό μ¬μ μνλ κ²κ³Ό κ°μ μ λ€λ¦ λ·°μ μ μ¬ν κΈ°μ μ μ¬μ©νμ¬ λ·°μ
μ 컀μ€ν°λ§μ΄μ§ν μ μμ΅λλ€.
μ λ€λ¦ λ·° 컀μ€ν°λ§μ΄μ§μ λν μ μμ κ³ λ € μ¬ν
μ μ κ³ κ°μ μν΄ μ λ€λ¦ λ·°λ₯Ό 컀μ€ν°λ§μ΄μ§ν λλ λ€μ μ¬νμ μΌλμ λμμμ€.
- μ§μν λ° κ΅μ ν(L10n/I18n): ν νλ¦Ώκ³Ό νΌμ΄ μ¬λ¬ μΈμ΄μ μ§μ νμμ μ§μνλμ§ νμΈν©λλ€. Djangoμ κΈ°λ³Έ μ 곡 i18n/l10n κΈ°λ₯μ μ¬μ©ν©λλ€.
- μκ°λ: μκ°λ λ³νμ μ¬λ°λ₯΄κ² μ²λ¦¬νμ¬ λ μ§μ μκ°μ μ¬μ©μ νμ§ μκ°μΌλ‘ νμν©λλ€. Djangoμ
timezone
λͺ¨λμ μ¬μ©ν©λλ€. - ν΅ν νμ: λ€μν μ§μμ μ ν©νκ² ν΅ν κ°μ νμνν©λλ€. ν΅ν νμ μ§μ μ μν΄
babel
κ³Ό κ°μ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ¬μ©νλ κ²μ κ³ λ €ν©λλ€. - λ μ§ λ° μ«μ νμ: μ¬μ©μ λ‘μΌμΌμ κΈ°λ°μΌλ‘ μ μ ν λ μ§ λ° μ«μ νμμ μ¬μ©ν©λλ€.
- μ κ·Όμ±: μ¬μ©μ μ§μ λ λ·°μ ν νλ¦Ώμ΄ μ₯μ κ° μλ μ¬μ©μκ° μ‘μΈμ€ν μ μλμ§ νμΈν©λλ€. WCAGμ κ°μ μ κ·Όμ± μ§μΉ¨μ λ°λ¦ λλ€.
- λ°μν λμμΈ: ν νλ¦Ώμ΄ λ°μνμ΄κ³ μ μΈκ³ μ¬μ©μκ° μ¬μ©νλ λ€μν νλ©΄ ν¬κΈ° λ° μ₯μΉμ λ§κ² μ‘°μ λλμ§ νμΈν©λλ€.
- λ¬Ένμ κ°μμ±: λ·°μ ν νλ¦Ώμ λμμΈν λ λ¬Ένμ μ°¨μ΄μ μ μνμμμ€. νΉμ λ¬ΈνκΆμ λΆμΎκ°μ μ€ μ μλ μ΄λ―Έμ§λ μΈμ΄λ₯Ό μ¬μ©νμ§ λ§μμμ€. μλ₯Ό λ€μ΄ μμ μ°κ΄μ± λ° κΈ°νΈλ λ¬ΈνκΆμ λ°λΌ λ§€μ° λ€λ₯Έ μλ―Έλ₯Ό κ°μ§ μ μμ΅λλ€.
μ: μκ°λ μ²λ¦¬
μ¬μ©μ νμ§ μκ°λλ‘ κ²μ λ μ§λ₯Ό νμνλ €λ©΄ ν
νλ¦Ώμμ timezone
νκ·Έλ₯Ό μ¬μ©ν μ μμ΅λλ€.
{% load tz %}
<p>κ²μμΌ: {% timezone article.publication_date %}</p>
Django μ€μ νμΌμ USE_TZ = True
κ° μλμ§ νμΈνμμμ€.
μ λ€λ¦ λ·° 컀μ€ν°λ§μ΄μ§μ λν λͺ¨λ² μ¬λ‘
λ€μ λͺ¨λ² μ¬λ‘λ₯Ό λ°λΌ 컀μ€ν°λ§μ΄μ§μ΄ μ μ§ κ΄λ¦¬ κ°λ₯νκ³ ν¨μ¨μ μΈμ§ νμΈνμμμ€.
- κ°λ¨νκ² μ μ§νμμμ€. 컀μ€ν°λ§μ΄μ§μ μ§λμΉκ² 볡μ‘νκ² λ§λ€μ§ λ§μμμ€. μνλ κ²°κ³Όλ₯Ό λ¬μ±νλ κ°μ₯ κ°λ¨ν κΈ°μ μ μ¬μ©νμμμ€.
- μ½λλ₯Ό λ¬Έμννμμμ€. 컀μ€ν°λ§μ΄μ§κ³Ό κ·Έ μ΄μ λ₯Ό μ€λͺ νλ μ£Όμμ μΆκ°νμμμ€.
- μ² μ ν ν μ€νΈνμμμ€. 컀μ€ν°λ§μ΄μ§μ΄ μ¬λ°λ₯΄κ² μλνλμ§ νμΈνκΈ° μν΄ λ¨μ ν μ€νΈλ₯Ό μμ±νμμμ€.
- λ―Ήμ€μΈμ νλͺ νκ² μ¬μ©νμμμ€. μΌλ°μ μΈ κΈ°λ₯μ μΊ‘μννκΈ° μν΄ μ¬μ¬μ© κ°λ₯ν λ―Ήμ€μΈμ λ§λμμμ€.
- Djangoμ κ·μΉμ λ°λ₯΄μμμ€. Djangoμ μ½λ© μ€νμΌκ³Ό λͺ λͺ κ·μΉμ μ€μνμμμ€.
- 보μμ κ³ λ €νμμμ€. λ·°λ₯Ό 컀μ€ν°λ§μ΄μ§ν λ μ μ¬μ μΈ λ³΄μ μ·¨μ½μ±μ μ μνμμμ€. μ¬μ©μ μ λ ₯μ μμ νκ³ κ΅μ°¨ μ¬μ΄νΈ μ€ν¬λ¦½ν (XSS) λ° SQL μ½μ κ³Ό κ°μ μΌλ°μ μΈ κ³΅κ²©μΌλ‘λΆν° 보νΈνμμμ€.
κ²°λ‘
Djangoμ ν΄λμ€ κΈ°λ° μ λ€λ¦ λ·°λ μΉ μ ν리μΌμ΄μ μ ꡬμΆνλ κ°λ ₯νκ³ μ μ°ν λ°©λ²μ μ 곡ν©λλ€. μ΄ κ°μ΄λμ μ€λͺ λ 컀μ€ν°λ§μ΄μ§ κΈ°μ μ λ§μ€ν°νλ©΄ μ λ€λ¦ λ·°λ₯Ό νΉμ μꡬ μ¬νμ λ§κ² μ‘°μ νμ¬ ν¨μ¨μ μ΄κ³ μ μ§ κ΄λ¦¬ κ°λ₯νλ©° μ μμ μΌλ‘ μ‘μΈμ€ν μ μλ μΉ μ ν리μΌμ΄μ μ λ§λ€ μ μμ΅λλ€. κ°λ¨ν μμ± μ¬μ μλΆν° 볡μ‘ν λ©μλ μ¬μ μ λ° λ―Ήμ€μΈ μ¬μ©μ μ΄λ₯΄κΈ°κΉμ§ κ°λ₯μ±μ 무κΆλ¬΄μ§ν©λλ€. μ μΈκ³μ μΈ κ΄μ κ³Ό λͺ¨λ² μ¬λ‘λ₯Ό κ³ λ €νμ¬ μ ν리μΌμ΄μ μ΄ λ€μν κ΅μ κ³ κ°μκ² μ ν©νλλ‘ νμμμ€.