IT 툴툴

[Django파이썬웹프로그래밍] 03 Django 웹 프레임워크 - 3.6~3.7

은듄 2021. 11. 22. 08:31
반응형

이어서 꼬~

 

개발 들어가기 전에 polls 애플리케이션이 생성된 후 반영을 위해선

 

settings.py 를 수정해 주어야 한다.

# cd /프로젝트/프로젝트폴더
# notepad settings.py

...

# Allowd Hosts _ Dev Type
ALLOWED_HOSTS = ['192.168.56.101', 'localhost', '127.0.0.1'] # 개발용 대역!

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls.apps.PollsConfig',			# polls 애플리케이션 경로의 설정 파일 경로 추가
]

...

자 이제 시작~


3.6 애플리케이션 개발하기 - Model 코딩


모델 작업은 데이터베이스에 테이블을 생성하는 작업이다.

 

notepad models.py					# 테이블을 정의함
notepad admins.py					# 정의된 테이블이 Admin 화면에 보이게 함
python manage.py makemigrations				# 데이터베이스에 변경이 필요한 사항을 추출함
python manage.py migrate				# 데이터베이스에 변경사항을 반영함
python manage.py runserver				# 현재까지 작업을 개발용 웹 서버로 확인함

 

3.6.1 테이블 정의

 

polls/models.py - Question 과 Choice 두 개의 테이블 생성하기

 

# cd /프로젝트/polls
# notepad models.py

from django.db import models

# Create your models here.

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text


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

 

3.6.2 Admin 사이트에 테이블 반영

 

polls/admin.py - Admin 사이트에 Question 과 Choice 두 개의 생성 테이블을 반영하기

# cd /프로젝트/polls
# notepad admin.py

from django.contrib import admin
from polls.models import Question, Choice

# Register your models here.
# admin.site.register() 함수를 사용하여 임포트한 클래스를 Admin 사이트에 등록

admin.site.register(Question)
admin.site.register(Choice)

 

3.6.3 데이터베이스 변경사항 반영

# VS Code Project Terminal 에 수행

python manage.py makemigrations				# 데이터베이스에 변경이 필요한 사항을 추출함
python manage.py migrate				# 데이터베이스에 변경사항을 반영함

아래는 수행 결과입니다.

[그림9] VS Code Terminal 수행 결과

뭔가 결과가 model을 생성하고, 해주는 아주 시원한 결과값이 나오죠?

다시 접속해보면,,

[그림10] 추가 테이블이 반영된 Admin 화면

짜잔~

 


3.7 애플리케이션 개발하기 - View 및 Template 코딩


다음 3개 페이지를 개발하기 위한 URL - View - Template 매핑 구성입니다.

 

[그림11] URL - View - Template 매핑

 

3.7.1 URLconf 코딩

 

 

URL 코딩 전에 프로젝트폴더/setting.py 중간에 ROOT_URLCONF = '프로젝트명.urls' 가 맞는지 확인하기!

 

[그림12] setting.py에 ROOT_URLCONF 위치 확인

 

아래의 URLs 파일에 작성 방법은 두가지 방법이 있고, 필자는 [방법2]를 추천한다!

 

[방법1] ROOT_URL(프로젝트폴더/urls.py) 에만 코딩하기

프로젝트폴더/urls.py - URL 코딩하기

# cd /프로젝트폴더
# notepad urls.py

from django.contrib import admin
from django.urls import path
from polls import views

urlpatterns = [
    path('admin/', admin.site.urls),
    
    path('polls/', views.index, name='index'),
    path('polls/<int:question_id>/', views.detail, name='detail'),
    path('polls/<int:question_id>/results/', views.results, name='results'),
    path('polls/<int:question_id>/vote/', views.vote, name='vote'),
]

[방법2] 프로젝트폴더/urls.py, 애플리케이션/urls.py에 나눠서 코딩하기

/프로젝트폴더/urls.py - URL 코딩하기

# cd /프로젝트폴더
# notepad urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),

    path('polls/', include('polls.urls')),
]

/polls/urls.py - URL 코딩하기 - 2

# cd /polls
# notepad urls.py

from django.urls import path
from polls import views

app_name = 'polls'
urlpatterns = [
    path('', views.index, name='index'),      # /polls/
    path('<int:question_id>/', views.detail, name='detail'),       # /polls/5/
    path('<int:question_id>/results/', views.results, name='results'),     # /polls/5/results/
    path('<int:question_id>/vote/', views.vote, name='vote'),      # /polls/5/vote/
]

[방법2]가 확장성이 더 좋다!

 

 

 

3.7.2-3.7.5 뷰 함수 index(), detail(), vote(), results() 및 템플릿, 리다이렉션 작성

 

아래는 먼저, Teamplate 폴더를 만들기

# VS Code Project Terminal 에 수행

cd /polls/				# 애플리케이션폴더
mkdir templates				# 템플릿폴더 만들기
mkdir templates/polls			# 템플릿폴더 내 애플리케이션용 템플릿 폴더 만들기

/애플리케이션폴더/template/polls/ 위치에 템플릿 파일 3개 만들기

# cd /polls/template/polls/index.html

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

index.html

# cd /polls/template/polls/detail.html

<h1>{{ question.question_text }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %} # 보안측면에서 CSRF 공격을 주의해야하기에 넣어 놓음
{% 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>

detail.html

# cd /polls/template/polls/results.html

<h1>{{ question.question_text }}</h1>

<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>

<a href="{% url 'polls:detail' question.id %}">Vote again?</a>

results.html

 

다음 Views 파일에 생성한 템플릿 파일 정의하고 매핑하기

 

# cd /polls/views.py

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.urls import reverse

from polls.models import Choice, Question


def index(request):
    latest_question_list = Question.objects.all().order_by('-pub_date')[:5]
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

def results(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/results.html', {'question': question})

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'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

 

소스코드는 항상 한줄씩 꼭 리뷰해봐야 한다.

이유 없는 코드는 없다.

 

 

 

3.7.6 지금까지 작업 확인하기

 

[그림12] 작성 완료되었으면 RUN SERVER!

실행에 이상 없으면, http://127.0.0.1:8000/polls 를 웹브라우져에서 열어보자.

[그림13] polls 페이지 결과

현재는 이렇게 나오는게 정상.

왜냐하면 데이터가 없기 때문에 ㅎㅎ

(index.html 에 데이터가 없으면, 아래와 같이 정의 해놓았음.)

 

다시 http://127.0.0.1:8000/admin 로 돌아가서 Questions을 추가 해보자.

 

[그림14] Question 추가하기

3개 정도 질문 추가 해보기.

 

[그림15] 질문 추가화면

아래는 추가한 화면이다.

 

[그림16] 질문 3개 추가한 화면

아래는 질문에 대한 선지 추가하는 화면이다.

 

[그림17] 선지 추가하기

아래는 각 질문 당 여러개 씩 선지를 만들어보자.

 

[그림18] 선지 추가하는 화면

선지 추가 완료!!

 

[그림19] 선지 추가한 화면

다시 http://127.0.0.1:8000/polls 보면,, 짜잔!

 

[그림20] 추가한 후 결과

투표도 해보자~ ㅎㅎ

 

[그림21] 결과 화면&amp;gt;&amp;lt;

 

3장은 여기까지~

어드민 화면이 이렇게 잘 개발되어있는게 신기하네요!

 

 

반응형