$ django-admin startproject mysite #프로젝트 생성
$ python manage.py runserver #개발 서버 실행
$ python manage.py startapp polls #설문조사 앱 생성
#polls/views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
- view를 호출하려면 연결된 URL이 필요하므로 URLconf를 생성하여 polls에 urls.py 생성한다
#polls/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
- 최상위 URLconf 에서 polls.urls 모듈을 바라보게 설정
#mysite/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
- include() 함수는 다른 URLconf들을 참조할 수 있도록 도와주며 Django가 함수 include() 를 만나게 되면, URL의 그 시점까지 일치하는 부분을 잘라내고, 남은 문자열 부분을 후속 처리를 위해 include 된 URLconf로 전달한다
- 모델이란 부가적인 메타데이터를 가진 데이터베이스의 구조이다
- 데이터베이스의 각 필드는 Field 클래스의 인스턴스로서 표현되며 각 필드가 어떤 자료형을 가질 수 있는지를 Django 에게 말해준다.
- makemigrations은 모델의 변경사항을 migration으로 저장시키고 싶다는 것을 Django에게 알려준다
$ python manage.py makemigrations polls
- migrate 명령은 아직 적용되지 않은 migration을 모두 수집해 이를 실행하며 모델에서의 변경 사항들과 데이터베이스의 스키마의 동기화가 이루어집니다.
$ python manage.py migrate
- Question model
class Question(models.Model):
question_text = models.CharField(max_length=200) #CharField => 문자(character) 필드
pub_date = models.DateTimeField('date published') # DateTimeField => 날짜와 시간(datetime) 필드
def __str__(self):
return self.question_text
def was_published_recently(self): #시간 관련 커스텀 메소드
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
- Choice model
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self): #객체를 표현하는 메소드
return self.choice_text
- HttpResponse - 객체를 반환
#polls.views.py from django.http import HttpResponse ... return HttpResponse(output)
- render() - HttpResponse 객체와 함께 돌려주는 구문을 쉽게 표현할 수 있도록 하는 단축 기능
#polls.views.py from django.shortcuts import render ... return render(request, 'polls/index.html', context)
- Http404 - 404에러 일으키기
from django.http import Http404 from django.shortcuts import render from .models import Question ... def detail(request, question_id): try: question = Question.objects.get(pk=question_id) except Question.DoesNotExist: raise Http404("Question does not exist") return render(request, 'polls/detail.html', {'question': question})
- get_object_or_404() - Http404 예외를 발생시키는 단축기능
from django.shortcuts import get_object_or_404, render from .models import Question ... def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question})
- 템플릿에 링크를 적으면, 이 링크는 다음과 같이 부분적으로 하드코딩된다
#polls/index.html <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
- polls.urls 모듈의 path() 함수에서 인수의 이름을 정의했으므로, {% url %} template 태그를 사용하여 url 설정에 정의된 특정한 URL 경로들의 의존성을 제거할 수 있다.
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
<input type="submit" value="Vote">
</form>
- form으로 제출된 데이터를 처리하고 그 데이터로 vote() 함수를 사용하여 정보를 저장한다.
def vote(request, question_id): question = get_object_or_404(Question, pk=question_id) try: selected_choice = question.choice_set.get(pk=request.POST['choice']) # 선택된 설문의 ID를 문자열로 반환 except (KeyError, Choice.DoesNotExist): return render(request, 'polls/detail.html', { 'question': question, 'error_message': "You didn't select a choice.", }) else: selected_choice.votes += 1 selected_choice.save() return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
-
제너릭 뷰는 일반적인 패턴을 추상화하여 앱을 작성하기 위해 Python 코드를 작성하지 않아도 된다.
-
ListView - 개체 목록 표시 추상화
``` class IndexView(generic.ListView): template_name = 'polls/index.html' # "polls/index.html" 템플릿을 사용하기 위해 ListView 에 template_name 를 전달 context_object_name = 'latest_question_list' def get_queryset(self): """Return the last five published questions.""" return Question.objects.order_by('-pub_date')[:5] ```
-
DetailView - 특정 개체 유형에 대한 세부 정보 페이지 표시
class DetailView(generic.DetailView): model = Question template_name = 'polls/detail.html' # <app name>/<model name>_detail.html 템플릿을 사용