교재
https://wikidocs.net/book/4223
Model
데이터 정의
→ model.py
Template
화면 정의
→ templates 디렉터리 하위에 *.html
파일
View
어플리케이션의 흐름 제어
→ views.py
하나의 (물리) 머신에 독립된 파이썬 실행 환경을 만들어주는 것
C:\python> python --version
Python 3.12.2
C:\python> pip list
Package Version
--------------- -----------
Faker 23.3.0 → #1
pip 24.0
PyMySQL 1.1.0
python-dateutil 2.9.0.post0
six 1.16.0
C:\python> python -m venv mysite
~~~~~~
# 가상 환경 이름 → 동일한 이름의 디렉터리가 생성
C:\python> .\mysite\Scripts\activate
~~~~~~ ~~~~~~~ ~~~~~~~~
(mysite) C:\python>
~~~~~~~~
# 가상 환경으로 진입해 작업하는 것을 의미
(mysite) C:\python> pip list
Package Version
------- -------
pip 24.0 → #1과는 다른 새로운 환경인 것을 확인
(mysite) C:\python> pip install faker==22.7.0
Collecting faker==22.7.0
Downloading Faker-22.7.0-py3-none-any.whl.metadata (15 kB)
Collecting python-dateutil>=2.4 (from faker==22.7.0)
Using cached python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)
Collecting six>=1.5 (from python-dateutil>=2.4->faker==22.7.0)
Using cached six-1.16.0-py2.py3-none-any.whl.metadata (1.8 kB)
Downloading Faker-22.7.0-py3-none-any.whl (1.7 MB)
---------------------------------------- 1.7/1.7 MB 3.2 MB/s eta 0:00:00
Using cached python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)
Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: six, python-dateutil, faker
Successfully installed faker-22.7.0 python-dateutil-2.9.0.post0 six-1.16.0
(mysite) C:\python> pip list
Package Version
--------------- -----------
Faker 22.7.0 → 패키지가 설치 되었는지 확인
pip 24.0
python-dateutil 2.9.0.post0
six 1.16.0
(mysite) C:\python> set path → PATH 환경변수 확인
Path=C:\python\mysite\Scripts;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\crpark\AppData\Local\Programs\Python\Python312\Scripts\;C:\Users\crpark\AppData\Local\Programs\Python\Python312\;C:\Users\crpark\AppData\Local\Microsoft\WindowsApps;C:\Users\crpark\AppData\Local\Programs\Microsoft VS Code\bin
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
(mysite) C:\python> deactivate → 가상 환경 내에서는 PATH 환경변수에
해당 경로가 등록되어 있으므로
어느 경로에서나 명령어 실행이 가능
C:\python> set path → 가상 환경과 관련한 경로가 포함 X
Path=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\crpark\AppData\Local\Programs\Python\Python312\Scripts\;C:\Users\crpark\AppData\Local\Programs\Python\Python312\;C:\Users\crpark\AppData\Local\Microsoft\WindowsApps;C:\Users\crpark\AppData\Local\Programs\Microsoft VS Code\bin
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
C:\python> pip list
Package Version
--------------- -----------
Faker 23.3.0 → 가상 환경에서 설치한 Faker 모듈과
버전이 상이한 것을 확인
pip 24.0
PyMySQL 1.1.0
python-dateutil 2.9.0.post0
six 1.16.0
C:\python> python -m venv yoursite
C:\python> .\yoursite\Scripts\activate
(yoursite) C:\python>
(yoursite) C:\python> pip list
Package Version
------- -------
pip 24.0
(yoursite) C:\python> pip install faker==20.1.0
Collecting faker==20.1.0
Downloading Faker-20.1.0-py3-none-any.whl.metadata (15 kB)
Collecting python-dateutil>=2.4 (from faker==20.1.0)
Using cached python_dateutil-2.9.0.post0-py2.py3-none-any.whl.metadata (8.4 kB)
Collecting six>=1.5 (from python-dateutil>=2.4->faker==20.1.0)
Using cached six-1.16.0-py2.py3-none-any.whl.metadata (1.8 kB)
Downloading Faker-20.1.0-py3-none-any.whl (1.7 MB)
---------------------------------------- 1.7/1.7 MB 9.2 MB/s eta 0:00:00
Using cached python_dateutil-2.9.0.post0-py2.py3-none-any.whl (229 kB)
Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: six, python-dateutil, faker
Successfully installed faker-20.1.0 python-dateutil-2.9.0.post0 six-1.16.0
(yoursite) C:\python> pip list
Package Version
--------------- -----------
Faker 20.1.0
pip 24.0
python-dateutil 2.9.0.post0
six 1.16.0
(yoursite) C:\python> deactivate
C:\python> pip list
Package Version
--------------- -----------
Faker 23.3.0 → 가상 환경과 무관하게 버전이 유지되는 것을 확인
pip 24.0
PyMySQL 1.1.0
python-dateutil 2.9.0.post0
six 1.16.0
c:\python> mkdir projects\mysite
c:\python> cd projects\mysite
c:\python\projects\mysite>
c:\python\projects\mysite> c:\python\mysite\Scripts\activate
(mysite) c:\python\projects\mysite>
(mysite) c:\python\projects\mysite> pip install django==3.1.3
Collecting django==3.1.3
Downloading Django-3.1.3-py3-none-any.whl.metadata (3.7 kB)
Collecting asgiref<4,>=3.2.10 (from django==3.1.3)
Downloading asgiref-3.7.2-py3-none-any.whl.metadata (9.2 kB)
Collecting pytz (from django==3.1.3)
Downloading pytz-2024.1-py2.py3-none-any.whl.metadata (22 kB)
Collecting sqlparse>=0.2.2 (from django==3.1.3)
Downloading sqlparse-0.4.4-py3-none-any.whl.metadata (4.0 kB)
Downloading Django-3.1.3-py3-none-any.whl (7.8 MB)
---------------------------------------- 7.8/7.8 MB 27.8 MB/s eta 0:00:00
Downloading asgiref-3.7.2-py3-none-any.whl (24 kB)
Downloading sqlparse-0.4.4-py3-none-any.whl (41 kB)
---------------------------------------- 41.2/41.2 kB 2.1 MB/s eta 0:00:00
Downloading pytz-2024.1-py2.py3-none-any.whl (505 kB)
---------------------------------------- 505.5/505.5 kB 31.0 MB/s eta 0:00:00
Installing collected packages: pytz, sqlparse, asgiref, django
Successfully installed asgiref-3.7.2 django-3.1.3 pytz-2024.1 sqlparse-0.4.4
(mysite) c:\python\projects\mysite> pip list
Package Version
--------------- -----------
asgiref 3.7.2
Django 3.1.3
Faker 22.7.0
pip 24.0
python-dateutil 2.9.0.post0
pytz 2024.1
six 1.16.0
sqlparse 0.4.4
(mysite) c:\python\projects\mysite> pip install setuptools
→ python 3.12 버전에서 삭제된 도구 설치
python 3.11 버전에서 기본적으로 포함되어 있음
Collecting setuptools
Using cached setuptools-69.1.1-py3-none-any.whl.metadata (6.2 kB)
Using cached setuptools-69.1.1-py3-none-any.whl (819 kB)
Installing collected packages: setuptools
Successfully installed setuptools-69.1.1
(mysite) c:\python\projects\mysite> django-admin startproject config .
→ 현재 디렉터리를 프로젝트 디렉터리로 만들라는 의미
(mysite) c:\python\projects\mysite> tree . /f
폴더 PATH의 목록입니다.
볼륨 일련 번호는 9027-83B9입니다.
C:\PYTHON\PROJECTS\MYSITE
│ manage.py
│
└─config
asgi.py
settings.py
urls.py
wsgi.py
__init__.py
(mysite) c:\python\projects\mysite> code .
(mysite) c:\python\projects\mysite> python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
March 08, 2024 - 11:14:34
Django version 3.1.3, using settings 'config.settings' # 설정 파일
Starting development server at http://127.0.0.1:8000/ # 접속 주소
Quit the server with CTRL-BREAK. # 서버 중지 방법 (Ctrl + C)
특정 기능을 수행하는 웹 애플리케이션
(mysite) c:\python\projects\mysite> django-admin startapp pybo
~~~~ # 앱 이름
(mysite) c:\python\projects\mysite> tree .\pybo /f
폴더 PATH의 목록입니다.
볼륨 일련 번호가 0000001B 9027:83B9입니다.
C:\PYTHON\PROJECTS\MYSITE\PYBO
│ admin.py
│ apps.py
│ models.py
│ tests.py
│ views.py
│ __init__.py
│
└─migrations
__init__.py
(mysite) c:\python\projects\mysite> python manage.py runserver
config/urls.py 파일에 path() 함수를 사용해서 URL과 요청을 처리할 함수 연결
from django.contrib import admin
from django.urls import path
from pybo import views
urlpatterns = [
path('admin/', admin.site.urls),
path('pybo/', views.index) → views.py 파일에 index 함수는 아직 구현 X
]
:
File "C:\Users\crpark\AppData\Local\Programs\Python\Python312\Lib\importlib\__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 995, in exec_module
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "c:\python\projects\mysite\config\urls.py", line 22, in <module>
path('pybo/', views.index)
^^^^^^^^^^^
AttributeError: module 'pybo.views' has no attribute 'index'
→ 뷰 함수가 정의되지 않았기 때문에 오류 발생
pybo\views.py 파일에 index() 함수 추가
from django.shortcuts import render
from django.http import HttpResponse → 요청에 대한 응답을 만들 때 사용하는 클래스
def index(request):
return HttpResponse("안녕하세요. PYBO에 온 것을 환영합니다.")
C:\Users\r2com> curl http://localhost:8000/pybo/ -v
* Trying [::1]:8000... # 개발 서버와 연결을 시도
* Trying 127.0.0.1:8000...
* Connected to localhost (127.0.0.1) port 8000
> GET /pybo/ HTTP/1.1 # 요청 시작
> Host: localhost:8000 # 요청 헤더 시작
> User-Agent: curl/8.4.0
> Accept: */*
> # 요청 헤더 끝
(GET 방식인 경우 요청 본문은 생략)
< HTTP/1.1 200 OK # 응답 시작
< Date: Fri, 08 Mar 2024 04:32:44 GMT # 응답 헤더 시작
< Server: WSGIServer/0.2 CPython/3.12.2
< Content-Type: text/html; charset=utf-8
< X-Frame-Options: DENY
< Content-Length: 52
< X-Content-Type-Options: nosniff
< Referrer-Policy: same-origin
< # 응답 헤더 끝
안녕하세요. PYBO에 온 것을 환영합니다. # 응답 본문
→ index 함수에서 HttpResponse
인스턴스 생성 시 입력한 문자열
* Connection #0 to host localhost left intact
앱 별로 URL 맵핑을 관리
from django.contrib import admin
from django.urls import path, include
from pybo import views
urlpatterns = [
path('admin/', admin.site.urls),
# path('pybo/', views.index),
# pybo 패키지에 있는 urls 모듈을 참조해서 URL 맵핑을 처리
→ pybo\urls.py 파일에 pybo/ 패턴의 요청을 처리할 URL 맵핑을 정의
path('pybo/', include('pybo.urls'))
]
from django.urls import path
from . import views # 현재 패키지에서 views 모듈을 가져옴
urlpatterns = [
path('', views.index),
]
DB에 변경 사항 적용
마이그레이션이 적용되지 않은 것이 존재
(mysite) c:\python\projects\mysite> python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
March 08, 2024 - 14:08:05
Django version 3.1.3, using settings 'config.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[08/Mar/2024 14:08:08] "GET /pybo/ HTTP/1.1" 200 52
기본 설치된 앱
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
장고 애플리케이션에서 사용하는 데이터베이스의 연결 정보
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
(mysite) c:\python\projects\mysite> 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 auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
C:\Program Files\DB Browser for SQLite\DB Browser for SQLite.exe 실행
from django.db import models
# 질문 모델 클래스를 정의
class Question(models.Model):
# 질문 모델이 가지는 속성을 정의
subject = models.CharField(max_length=200) # 글자 수 제한이 있는 데이터
content = models.TextField() # 글자 수 제한이 없는 데이터
create_date = models.DateTimeField() # 날짜, 시간을 나타내는 데이터
# 답변 모델 클래스를 정의
class Answer(models.Model):
# 답변 모델이 가지는 속성을 정의
question = models.ForeignKey(Question, on_delete=models.CASCADE)
content = models.TextField()
create_date = models.DateTimeField()
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'pybo.apps.PyboConfig', # 장고가 pybo 앱을 인식하고
데이터베이스 관련 작업을 수행할 수 있음
]
(mysite) c:\python\projects\mysite> python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
No migrations to apply.
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~
# 장고가 테이블 작업을 수행하기 위한 파일 생성 # 실제 테이블 생성
(mysite) c:\python\projects\mysite> python manage.py makemigrations
Migrations for 'pybo':
pybo\migrations\0001_initial.py
- Create model Question
- Create model Answer
(mysite) c:\python\projects\mysite> dir pybo\migrations
# 마이그레이션 파일이 있는 위치
C 드라이브의 볼륨에는 이름이 없습니다.
볼륨 일련 번호: 9027-83B9
c:\python\projects\mysite\pybo\migrations 디렉터리
2024-03-08 오후 03:02 <DIR> .
2024-03-08 오후 03:02 <DIR> ..
2024-03-08 오후 03:02 1,104 0001_initial.py
2024-03-08 오후 01:09 0 __init__.py
2024-03-08 오후 03:02 <DIR> __pycache__
2개 파일 1,104 바이트
3개 디렉터리 172,790,190,080 바이트 남음
(mysite) c:\python\projects\mysite> type pybo\migrations\0001_initial.py
# Generated by Django 3.1.3 on 2024-03-08 06:02
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Question',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('subject', models.CharField(max_length=200)),
('content', models.TextField()),
('create_date', models.DateTimeField()),
],
),
migrations.CreateModel(
name='Answer',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content', models.TextField()),
('create_date', models.DateTimeField()),
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pybo.question')),
],
),
]
(mysite) c:\python\projects\mysite> python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, pybo, sessions
Running migrations:
Applying pybo.0001_initial... OK
장고 실행에 필요한 환경들을 자동으로 설정해서 실행하는 쉘 (!=python shell)
(mysite) c:\python\projects\mysite> python manage.py shell
Python 3.12.2 (tags/v3.12.2:6abddd9, Feb 6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
>>> from pybo.models import Question, Answer
>>> from django.utils import timezone
>>> q = Question(subject='pybo가 무엇인가요?', content='pybo에 대해서 알려 주세요', create_date=timezone.now())
>>> q.save() # 모델 데이터를 데이터베이스에 저장
>>> q.subject
'pybo가 무엇인가요?'
>>> q.id # 장고가 자동으로 넣어 주는 필드
1
>>> q = Question(subject='두번째 질문입니다.', content='ID는 자동으로 생성되나요?', create_date=timezone.now())
>>> q.save()
>>> q.id
2
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>, <Question: Question object (2)>]>
^ ^
# 장고가 Question 모델 데이터에 자동으로 입력한 ID 값
기본적으로 ID 출력
from django.db import models
# 질문 모델 클래스를 정의
class Question(models.Model):
# 질문 모델이 가지는 속성을 정의
subject = models.CharField(max_length=200) # 글자 수 제한이 있는 데이터
content = models.TextField() # 글자 수 제한이 없는 데이터
create_date = models.DateTimeField() # 날짜, 시간을 나타내는 데이터
def __str__(self):
return self.subject # 제목을 반환
# 답변 모델 클래스를 정의
class Answer(models.Model):
# 답변 모델이 가지는 속성을 정의
question = models.ForeignKey(Question, on_delete=models.CASCADE)
content = models.TextField()
create_date = models.DateTimeField()
>>> exit()
(mysite) c:\python\projects\mysite> python manage.py shell
Python 3.12.2 (tags/v3.12.2:6abddd9, Feb 6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from pybo.models import Question, Answer
>>> Question.objects.all()
<QuerySet [<Question: pybo가 무엇인가요?>, <Question: 두번째 질문입니다.>]>
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
# 조건에 해당하는 데이터를 모두 찾아서 QuerySet 형태로 반환
>>> Question.objects.filter(id=1)
<QuerySet [<Question: pybo가 무엇인가요?>]>
>>> rs = Question.objects.filter(id=1)
>>> rs[0].subject
'pybo가 무엇인가요?'
# 조건을 만족하는 결과가 없는 경우 빈 QuerySet을 반환
>>> rs = Question.objects.filter(id=100)
>>> rs
<QuerySet []>
# 조건에 해당하는 데이터 중 하나만 해당 객체 타입으로 반환
>>> Question.objects.get(id=1)
<Question: pybo가 무엇인가요?>
>>> rs = Question.objects.get(id=1)
>>> rs.subject
'pybo가 무엇인가요?'
# 조건을 만족하는 결과가 없는 경우 오류가 발생
>>> rs = Question.objects.get(id=100)
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Users\crpark\AppData\Local\Programs\Python\Python312\Lib\site-packages\django\db\models\manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\crpark\AppData\Local\Programs\Python\Python312\Lib\site-packages\django\db\models\query.py", line 429, in get
raise self.model.DoesNotExist(
pybo.models.Question.DoesNotExist: Question matching query does not exist.
# 일치하는 것 조회
>>> Question.objects.filter(subject='인가요')
<QuerySet []>
# SQL의 LIKE 연산과 동일하게 동작
>>> Question.objects.filter(subject__contains='인가요')
<QuerySet [<Question: pybo가 무엇인가요?>]>
>>> q = Question.objects.get(id=1) # 수정 대상 조회 (get, filter)
>>> q
<Question: pybo가 무엇인가요?>
>>> q.subject = 'What is pybo?' # 객체 필터의 데이터를 변경
>>> q.save() # save 함수를 이용해서 DB에 반영
>>> q = Question.objects.get(id=1)
>>> q
<Question: What is pybo?>
>>> q = Question.objects.get(id=1)
>>> q.delete() # delete 메서드를 호출하면 DB에도 즉시 반영
(1, {'pybo.Question': 1})
>>> rs = Question.objects.all()
>>> rs
<QuerySet [<Question: 두번째 질문입니다.>]>
>>> q = Question.objects.get(id=2)
>>> q
<Question: 두번째 질문입니다.>
>>> from django.utils import timezone
>>> a = Answer(question=q, content='네 자동으로 생성됩니다.', create_date=timezone.now())
>>> a.save()
>>> a = Answer.objects.get(id=1)
>>> a
<Answer: Answer object (1)>
>>> a.question
<Question: 두번째 질문입니다.>
>>> q = Question.objects.get(id=2)
>>> q.answer_set.all() # 연결되어있는모델명_set 형식으로 참조
<QuerySet [<Answer: Answer object (1)>]>
>>> exit()
(mysite) c:\python\projects\mysite> python manage.py createsuperuser
Username (leave blank to use 'crpark'): admin
Email address: myanjini@gmail.com
Password: p@ssw0rd1234
Password (again): p@ssw0rd1234
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
(mysite) c:\python\projects\mysite> python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
March 08, 2024 - 16:48:25
Django version 3.1.3, using settings 'config.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
장고 admin을 통해 모델 관리가 가능
from django.contrib import admin
from .models import Question
admin.site.register(Question)
pybo\admin.py
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
search_fields = ['subject']
admin.site.register(Question, QuestionAdmin)
from django.shortcuts import render
from .models import Question
def index(request):
question_list = Question.objects.order_by('-create_date')
context = { 'question_list' : question_list }
return render(request, 'pybo/question_list.html', context)
템플릿 파일이 저장되는 위치
{% if question_list %}
<ul>
{% for question in question_list %}
<li><a href="/pybo/{{ question.id }}/">{{ question.subject }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>질문이 없습니다.</p>
{% endif %}
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [ BASE_DIR / 'templates' ],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]