반응형

3.1 일반적인 특징

파이썬 웹프로그래미이다.

MVC

하지만 장고에서는 ViewTemplate, ControllerView라고 부릅니다.

MVT

3.2 장고 프로그램 설치

C:\Users\NB-0308>python -V

Python 3.7.6

 

3.2.1 윈도우에서 장고 설치

pip install Django

설치 확인

python -m django –-version

 

pip install django-oauth-toolkit djangorestframework

pip install pymysql

pip install mysqlclient

pip install djangorestframework-jwt

pip install pyjwt

pip install djangorestframework_simplejwt

3.3 장고에서의 애플리케이션 개발 방식

3.3.1 MVT 패턴

모델은 데이터베이스에 저장되는 데이터를 의미하는 것이고

템플릿은 사용자에게 보여주는 uii부분

뷰는 실질적으로 프로그램 로직이 동작하여 데이터를 가져오고 적절하게 처리한 결과를 전달하는 역할 을 수행합니다.

3.3.2 Model – 데이터베이스 정의

3,3,3 URLconf-URL정의

3.3.4 View-로직 정의

3.3.5 Template -화면 UI정의

3.3.6 MVT 코딩 순서

프로젝트 뼈대 만들기

모델 코딩하기

URLconf 코딩하기

템플릿 코딩하기

뷰 코딩하기

3.4 애플리케이션 설계하기

프로젝트란 개발 대상이 되는 전체 프로그램을 의미하며 , 프로젝트를 몇 개의 기능 그룹으로 나누었을 때 , 프로젝트 하위의 서브 프로그램을 애플리케이션이라고 합니다.

즉 서버 프로그램인 애플리케이션을 개발하고 , 이들을 모아서 프로젝트 개발을 완성하게 되는 것입니다.

3.5.1 프로젝트 생성

C:\Users\NB-0308>cd c:\project

 

c:\project>mkdir webprogram

 

c:\project>cd webprogram

 

c:\project\webprogram>

 

c:\project\webprogram>django-admin startproject mysite

 

c:\project\webprogram>dir

 C 드라이브의 볼륨에는 이름이 없습니다.

 볼륨 일련 번호: FCA3-2376

 

 c:\project\webprogram 디렉터리

 

2020-06-18  오후 04:11    <DIR>          .

2020-06-18  오후 04:11    <DIR>          ..

2020-06-18  오후 04:11    <DIR>          mysite

               0개 파일                   0 바이트

               3개 디렉터리  135,499,644,928 바이트 남음

 

c:\project\webprogram>dir mysite

 C 드라이브의 볼륨에는 이름이 없습니다.

 볼륨 일련 번호: FCA3-2376

 

 c:\project\webprogram\mysite 디렉터리

 

2020-06-18  오후 04:11    <DIR>          .

2020-06-18  오후 04:11    <DIR>          ..

2020-06-18  오후 04:11               647 manage.py

2020-06-18  오후 04:11    <DIR>          mysite

               1개 파일                 647 바이트

               3개 디렉터리  135,499,579,392 바이트 남음

 

c:\project\webprogram>dir mysite\mysite

 C 드라이브의 볼륨에는 이름이 없습니다.

 볼륨 일련 번호: FCA3-2376

 

 c:\project\webprogram\mysite\mysite 디렉터리

 

2020-06-18  오후 04:11    <DIR>          .

2020-06-18  오후 04:11    <DIR>          ..

2020-06-18  오후 04:11               405 asgi.py

2020-06-18  오후 04:11             3,208 settings.py

2020-06-18  오후 04:11               769 urls.py

2020-06-18  오후 04:11               405 wsgi.py

2020-06-18  오후 04:11                 0 __init__.py

               5개 파일               4,787 바이트

               2개 디렉터리  135,499,579,392 바이트 남음

 

이름 바꾸기

c:\project\webprogram>move mysite ch3

        1개의 디렉터리를 이동했습니다.

 

c:\project\webprogram>

 

3.5.2 애플리케이션 생성

Polls는 원하는 애플리케이션 명칭을 입력하면 됩니다.

c:\project\webprogram>cd ch3

 

c:\project\webprogram\ch3>python manage.py startapp polls

 

c:\project\webprogram\ch3>dir

 C 드라이브의 볼륨에는 이름이 없습니다.

 볼륨 일련 번호: FCA3-2376

 

 c:\project\webprogram\ch3 디렉터리

 

2020-06-18  오후 04:18    <DIR>          .

2020-06-18  오후 04:18    <DIR>          ..

2020-06-18  오후 04:11               647 manage.py

2020-06-18  오후 04:18    <DIR>          mysite

2020-06-18  오후 04:18    <DIR>          polls

               1개 파일                 647 바이트

               4개 디렉터리  135,498,149,888 바이트 남음

 

c:\project\webprogram\ch3>dir polls

 C 드라이브의 볼륨에는 이름이 없습니다.

 볼륨 일련 번호: FCA3-2376

 

 c:\project\webprogram\ch3\polls 디렉터리

 

2020-06-18  오후 04:18    <DIR>          .

2020-06-18  오후 04:18    <DIR>          ..

2020-06-18  오후 04:18                66 admin.py

2020-06-18  오후 04:18                90 apps.py

2020-06-18  오후 04:18    <DIR>          migrations

2020-06-18  오후 04:18                60 models.py

2020-06-18  오후 04:18                63 tests.py

2020-06-18  오후 04:18                66 views.py

2020-06-18  오후 04:18                 0 __init__.py

               6개 파일                 345 바이트

               3개 디렉터리  135,498,149,888 바이트 남음

 

 

3.5.3 프로젝트 설정 파일 변경

프로젝트에 필요한 설정값들은 settings.py파일에 지정합니다.

Settings.py파일은 프로젝트의 전반적인 사항들을 설정해주는 곳으로 , 루트 디렉토리를 포함한 각종 디레토리의 위치 , 로그의 형식, 프로젝트에 포함된 애플리케이션의 이름 등이 지정되어 있습니다.

 

1.     ALLOWED_HOSTS 적절하게 지정해야 합니다.

DEBUG = True 개발모드로 , False이면 운영 모드로 인식합니다.

운영 모드인 경우는 ALLOWED_HOSTS에 반드시 서버의 Ip나 도메인을 지정해야 하고 , 개발 모드인 경우에는 값을 지정하지 않아도 locaolhost, 127.0.0.1로 간주

2.     프로젝트에 포함되는 애플리케이션들은 모든 설정 파일에 등록되어야 합니다. 따라서 우리가 개발하고 있는 polls 애플리케이션도 등록해야 합니다. 애플리케이션을 등록할 때는 간단하게 애플리케이션의 모듈명인 ‘polls’만 등록해도 되자만, 애플리케이션의 설정 클래스로 등록하는 것이 더 정확한 방법입니다.

poll앱의 설정 클래스는 startapp polls 명령 시에 자동 생성된 apps.py파일에 PollsConfig라고 정의 되어 있습니다. 그래서 장고가 설정 클래스를 찾을 수 있도록 모듈 결올까지 포함하여 ‘polls.apps.PollsConfig’ 라고 등록합니다.

 

INSTALLED_APPS = [

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'polls.apps.PollsConfig' #추가

]

3.     프로젝트에 사용할 데이터베이스 엔진입니다.

장고는 기본적으로 디폴트로 sqlite3데이터베이스 엔진을 사용하도록 설정되어 있습니다.

 

  • ENGINE -- 'django.db.backends.sqlite3''django.db.backends.postgresql''django.db.backends.mysql', 또는 'django.db.backends.oracle'. 그외에 서드파티 백엔드 참조.
  • NAME -- 데이터베이스의 이름. 만약 SQLite 사용 중이라면, 데이터베이스는 당신의 컴퓨터의 파일로서 저장됩니다. 경우NAME  파일명을 포함한 절대경로로 지정해야 합니다. 기본값은 os.path.join(BASE_DIR, 'db.sqlite3') 정의되어 있으며, 프로젝트 디렉토리 내에 db.sqlite3 파일로 저장됩니다.

SQLite 데이터베이스로 사용하지 않는 경우USERPASSWORDHOST 같은 추가 설정이 반드시 필요합니다. 자세한 내용은 DATABASES 문서를 참조해 주세요.

 

https://docs.djangoproject.com/ko/3.0/intro/tutorial02/

 

 

 

4.     타임존 지저ㅇ

TIME_ZONE = 'UTC'

 

#TIME_ZONE = 'UTC'

TIME_ZONE = 'Asia/Seoul'

 

3.5.5 기본 테이블 생성

c:\project\webprogram\ch3>python manage.py migrate

Operations to perform:

  Apply all migrations: admin, auth, contenttypes, sessions

Running migrations:

  Applying contenttypes.0001_initial... OK

  Applying auth.0001_initial... OK

  Applying admin.0001_initial... OK

  Applying admin.0002_logentry_remove_auto_add... OK

  Applying admin.0003_logentry_add_action_flag_choices... OK

  Applying contenttypes.0002_remove_content_type_name... OK

  Applying auth.0002_alter_permission_name_max_length... OK

  Applying auth.0003_alter_user_email_max_length... OK

  Applying auth.0004_alter_user_username_opts... OK

  Applying auth.0005_alter_user_last_login_null... OK

  Applying auth.0006_require_contenttypes_0002... OK

  Applying auth.0007_alter_validators_add_error_messages... OK

  Applying auth.0008_alter_user_username_max_length... OK

  Applying auth.0009_alter_user_last_name_max_length... OK

  Applying auth.0010_alter_group_name_max_length... OK

  Applying auth.0011_update_proxy_permissions... OK

Applying sessions.0001_initial... OK

 

c:\project\webprogram\ch3>dir

 C 드라이브의 볼륨에는 이름이 없습니다.

 볼륨 일련 번호: FCA3-2376

 

 c:\project\webprogram\ch3 디렉터리

 

2020-06-18  오후 04:46    <DIR>          .

2020-06-18  오후 04:46    <DIR>          ..

2020-06-18  오후 04:46           131,072 db.sqlite3

2020-06-18  오후 04:11               647 manage.py

2020-06-18  오후 04:18    <DIR>          mysite

2020-06-18  오후 04:46    <DIR>          polls

               2개 파일             131,719 바이트

               4개 디렉터리  134,454,546,432 바이트 남음

 

Migrate 명령은 데이터베이스에 변경사항이 있을 때 이를 반영해주는 명령입니다ㅣ.

이 명령이 필요한 이유 :

장고는 모든 웹 프로젝트 개발 시 반드시 사용자와 그룹 테이블 등이 필요하다는 가정하에 설계되었습니다. 그래서 우리가 테이블을 전혀 만들지 않았더라도 , 사용자 및 그룹 테이블 등을 만들어주기 위해서 프로젝트 개발 시작 시점에 이 명령을 실행하는 것입니다. 명령을 실행하면 migrate 명령에 대한 로그가 보이고 , 실행 결과로 sqlite3데이터베이스 파일인

db.sqlite3 파일이 생성된 것을 확인 할 수 있습니다.

 

3.5.5 지금 까지 작업 확인하기

runserver라고 하는 간단한 테스트용 웹서버를 제공해줍니다.

 

c:\project\webprogram\ch3>python manage.py runserver 0.0.0.0:8000

Watching for file changes with StatReloader

Performing system checks...

 

System check identified no issues (0 silenced).

June 18, 2020 - 17:00:56

Django version 3.0.7, using settings 'mysite.settings'

Starting development server at http://0.0.0.0:8000/

Quit the server with CTRL-BREAK.

[18/Jun/2020 17:00:56] "GET / HTTP/1.1" 200 16351

url에서 : http://localhost:8000/admin

정상

 

로그인 하려면 username, password를 넣어야 되는제 아직 생성하지 않았습니다.

c:\project\webprogram\ch3>python manage.py createsuperuser

Username (leave blank to use 'nb-0308'): user

Email address: haidanliu@dkitec.com

Password:

Password (again):

This password is too short. It must contain at least 8 characters.

This password is too common.

This password is entirely numeric.

Bypass password validation and create user anyway? [y/N]: y

Superuser created successfully.

 

user 0000

여기에서 usersgroups테이블이 보이는 것은 이미 settings.py파일에 Django.contrib.authGroups테이블이 미리 정의 되어 잇는 것입니다.

 

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

3.6.1 테이블 정의

c:\project\webprogram\ch3>cd polls

 

c:\project\webprogram\ch3\polls>notepad models.py

 

c:\project\webprogram\ch3\polls>

 

from django.db import models

 

# Create your models here.

class Question(models.Model):

           question_text = models.CharField(max_length=200)

           pub_date = models.DateTimeFiled('data 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

테이블을 하나의 class로 정의하고 , 테이블의 컬럼은 클래스의 변수(속성)로 매핑함

django..models.Model클래스를 상속받아 정의하고 , 각 클래스 변수의 타입도 장고에서 미리 정의된 필드 클래스를 사용합니다.

Id는 자동생성해준다.

Pk ;클래스에 정의해주지 않아도 장고는 항상 PK에 대한 속성을 Not NullAutoincrement로 이름은 id로 해서 자동으로 만들어줍니다.

DateTimeFiled()필드 클래스에 정의한 date published pub_Date컬럼에 대한 레이블 문구입니다. 나중에 설명하느 Admin사이트에서 이 문구를 보게 될 것입니다.

FK: 항상 다른 테이블의 pk에 연결된다.

__str__()메소드는 객체를 문자열로 표현할 때 사용하는 함수입니다. 나중에 보게 될 Admin사이트나 장고 쉘 등에서 테이블명을 보여줘야 하는뎅, 이때 __Str__()메소드를 정의하지 않으면 테이블명이 제대로 표시되지 않습니다. 파이썬 2에서는 __unicode__()메소드를 사용합니다.

 

3.6.2 Admin사이트에 테이블 변경

 

c:\project\webprogram\ch3\polls>notepad admin.py

from django.contrib import admin

from polls.models import Question, Choice

# Register your models here.

 

admin.site.register(Question)

admin.site.register(Choice)

 

오류 해결

pub_date = models.DateTimeFiled('data published')  =>

pub_date = models.DateTimeFiled('date published')

 

수정후 ㅊㅇ

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

import하고 한다.

 

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

c:\project\webprogram\ch3>python manage.py makemigrations

Migrations for 'polls':

  polls\migrations\0001_initial.py

    - Create model Question

    - Create model Choice

 

c:\project\webprogram\ch3>dir polls\migrations

 C 드라이브의 볼륨에는 이름이 없습니다.

 볼륨 일련 번호: FCA3-2376

 

 c:\project\webprogram\ch3\polls\migrations 디렉터리

 

2020-06-19  오전 10:51    <DIR>          .

2020-06-19  오전 10:51    <DIR>          ..

2020-06-19  오전 10:51             1,107 0001_initial.py

2020-06-18  오후 04:18                 0 __init__.py

2020-06-19  오전 10:51    <DIR>          __pycache__

               2개 파일               1,107 바이트

               3개 디렉터리  132,641,574,912 바이트 남음

 

c:\project\webprogram\ch3>python manage.py migrate

Operations to perform:

  Apply all migrations: admin, auth, contenttypes, polls, sessions

Running migrations:

  Applying polls.0001_initial... OK

 

c:\project\webprogram\ch3>

 

           python manage.py runserver 0.0.0.0:8000

 

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

3.7.1 URLconf코딩

c:\project\webprogram\ch3>cd mysite

 

c:\project\webprogram\ch3\mysite>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'),

]

필요한 모듈과 함수를 임포트합니다. Admin 모듈과 path()함순느 장고에서 제공하는 것이고 , Views모듈은 다음 절에서 코딩을 예정입니다.

URL/뷰 매핑을 정의하는 방식은 항상 동일하므로 , 그대로 따라서 코딩합니다. URL패턴 매칭은 위에서 아래로 진행하므로 ,정의하는 순서에 유의해야 합니다.

장고의 Admin사이트에 대한 URLconf는 이미 정의 되어 있는데 , 이를 활용하고 있습니다. Admin사이틀 사용하기 위해서는 항상 이렇게 정의한다고 알아두세요.

polls애플리케이션에 대한 URL/뷰 매핑을 정의하고 있습니다. PATH()함수를 중요하므로 따로 설명 합니다.

route: url패턴 ,url 스트링

view: url스트링이 매칭되면 호출되는 뷰 함수

kwargs: urlspring에서 추출된 항목 외에 추가적인 인자를 뷰 함수에 전달할 때  ,파이썬 사전 차입으로 인자를 정의합니다.

name: url패턴별로 이름을 붙여줍니다.

 

Admin : path('admin/', admin.site.urls),

요청이 polls 라면

path('polls/', views.index, name='index')

 

/polls/3

path('polls/<int:question_id>/', views.detail, name='detail')

 

 

polls/7/results/

path('polls/<int:question_id>/results/', views.results, name='results'),

 

polls/9/vote/

path('polls/<int:question_id>/vote', views.vote, name='vote'),

 

 

 

mysite/urls.py

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

'''
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'),
]
'''
urlpatterns = [
    path(
'admin/', admin.site.urls),
   
path('polls/',include('polls.urls')),
]

 

polls/urls.py

from django.urls import path
from . import views

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

 

 

3.7.2 뷰 함수 index()템플릿 작성

c:\project\webprogram\ch3>cd polls

 

c:\project\webprogram\ch3\polls>notepad urls.py

 

c:\project\webprogram\ch3\polls>mkdir templates

 

c:\project\webprogram\ch3\polls>mkdir templates\polls

 

c:\project\webprogram\ch3\polls>cd templates\polls

 

c:\project\webprogram\ch3\polls\templates\polls>notepad index.html

{% if latest_question_list %{
   
<ul>
   
# latest_question_list index()
    {% 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 %}

 

c:\project\webprogram\ch3\polls>notepad views.py

 

c:\project\webprogram\ch3\polls>

 

from django.shortcuts import render

# Create your views here.
from django.shortcuts import  render
from polls.models import 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)

 

 

3.7.3 뷰 함수 detail()및 폼 템플릿 작성

c:\project\webprogram\ch3\polls>cd templates

 

c:\project\webprogram\ch3\polls\templates>cd polls

 

c:\project\webprogram\ch3\polls\templates\polls>notepad detail.html

 

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

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

<from 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>
<% endfor %}
<input type = "submit" value="Vote" />
</from>

 

c:\project\webprogram\ch3\polls\templates\polls>notepad views.py

from django.shortcuts import  render, get_object_or_404
from polls.models import 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})

 

get_object_or_404()함수를 임포트핟로ㅗㄱ 함수명만 추가하였습니다.

Request는 필수 인자이고 , 추갖거으로 question_id인자를 더 받습니다.

Get_object_or_404()단축함수를 사용하고 있습니다. 이 함수의 첫번쨰 인자는 모델 클래스이고, 두번째 인자부터는 검색 조건을 여러 개 사용할 수 있습니다. 이 예제에서는 Question모델 클래스로 부터 pk = question_id검색 조건에 맞는 객체를 조회합니다. 조건에 맞는 객체가 없으면 Http404익셉션을 발생시킵니다.

Render()

Detail()

 

3.7.4 뷰 함수 vote() 및 리다이렉션 작성

Detail.html  -> vote버튼 클릭 ->

c:\project\webprogram\ch3\polls >notepad views.py

from django.shortcuts import render

# Create your views here.
from django.shortcuts import  render,get_object_or_404
from polls.models import Question
from django.http import HttpResponseRedirect
from polls.models import Choice,Question
from django.urls import reverse

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 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):
       
#설문 투표 폼을 다시 보여준다.
       
return render(request,'polls/detail.html',{
           
'question':question,
           
'error_message':"You didn't select a choice."
       
})
   
else:
        selected_choice.votes +=
1
       
selected_choice.save()
       
#POST데이터를 정상적으로 처리하였으면 ,
        #
항상 httpResponseRedirectㄹ르 반환하여 리다이렉션 처리함
       
#reverse url처리
       
return HttpResponseRedirect(reverse('polls:results',args=(question.id,)))

 

 

3.7.3 뷰 함수 results()및 템플릿 작성

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

 

 

c:\project\webprogram\ch3\polls\templates\polls>notepad results.html

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

<ul>
{% for chioce 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>

 

 

 

 

 

 

python manage.py runserver 0.0.0.0:8000

 

http://127.0.0.1:8000/polls/

 

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 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)

 

 

{% if latest_question_list %}
   
<ul>
   
# latest_question_list index()
    {% 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 %}

 

 

 

http://127.0.0.1:8000/admin/

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 %}

 

 

Detail.html

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

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

<from 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" />
</from>

 

 

 

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 %}
{% 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>

 

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>

http://127.0.0.1:8000/polls/

python manage.py runserver 0.0.0.0:8000

 

 

 

 

 

 

출처 : Django로 배우는 쉽고 빠른 웹 개발 파이썬 웹 프로그래밍

반응형

+ Recent posts